@@ -52,6 +52,10 @@ define register offset=0x600 size=4 [ EMACSR ACC0 ACC1 ACC2 ACC3 ACCext01 ACCext
52
52
@define DAT_DIR_CTL_ADDR_MODES2 "(mode2=0 | mode2=2 | mode2=5 | mode2=6 | mode=7)" # Data direct and control addressing modes
53
53
@define CTL_ADDR_MODES2 "(mode2=2 | mode2=5 | mode2=6 | mode2=7)" # Control addressing modes
54
54
55
+ @ifdef CPU32
56
+ @define TBL_ADDR_MODES "(tbl_mode=2 | tbl_mode=4 | tbl_mode=5 | tbl_mode=6 | tbl_mode=7)" # Addressing modes for tblxx instructions
57
+ @endif
58
+
55
59
# Floating-point condition code bits within FPSR
56
60
@define N_FP "FPSR[27,1]"
57
61
@define Z_FP "FPSR[26,1]"
@@ -149,8 +153,32 @@ define token extword (16)
149
153
sfact = (9,10)
150
154
accmsb = (4,4)
151
155
@endif
156
+ @ifdef CPU32 # Data register interpolation fields for TBL instructions.
157
+ tbl_dr_size = (6,7)
158
+ tbl_dr_round = (10,10)
159
+ tbl_dr_sign = (11,11)
160
+ tbl_dr_reg = (0,2)
161
+ @endif
152
162
;
153
163
164
+ @ifdef CPU32
165
+ # The TBLxx instructions are two 16-bit tokens optionally followed by a disp16 token.
166
+ # The presence of the disp16 token is governed by bits in the first token.
167
+ # Sleigh's ... operator follows the second token, but needs the bits from the first.
168
+ # To work around that, a single 32-bit token is used in place of the standard tokens.
169
+ define token tbl_instrA(32)
170
+ tbl_regan=(16,18)
171
+ tbl_mode=(19,21)
172
+ tbl_op37=(19,23)
173
+ tbl_op67=(22,23)
174
+ tbl_opbig=(24,31)
175
+ tbl_size=(6,7)
176
+ tbl_round=(10,10)
177
+ tbl_sign=(11,11)
178
+ tbl_regxdn=(12,14)
179
+ ;
180
+ @endif
181
+
154
182
define token extword2 (16)
155
183
regda2 = (12,15)
156
184
ext2_911 = (9,11)
@@ -281,7 +309,12 @@ define context contextreg
281
309
extGUARD = (14,14) # guard for saving off modes before starting instructions
282
310
;
283
311
312
+ @ifdef CPU32
313
+ attach variables [ regdn regxdn reg9dn regdr regdq regsdn regdu regdc regdu2 regdc2 tbl_regxdn tbl_dr_reg ] [ D0 D1 D2 D3 D4 D5 D6 D7 ];
314
+ @else
284
315
attach variables [ regdn regxdn reg9dn regdr regdq regsdn regdu regdc regdu2 regdc2 ] [ D0 D1 D2 D3 D4 D5 D6 D7 ];
316
+ @endif
317
+
285
318
attach variables [ fldoffreg fldwdreg f_reg fcnt fkfacreg fldynreg ] [ D0 D1 D2 D3 D4 D5 D6 D7 ];
286
319
attach variables [ regdnw regxdnw reg9dnw regsdnw regduw regdcw regdu2w regdc2w ] [ D0w D1w D2w D3w D4w D5w D6w D7w ];
287
320
attach variables [ regdnb reg9dnb regsdnb regdub regdcb ] [ D0b D1b D2b D3b D4b D5b D6b D7b ];
@@ -526,11 +559,13 @@ Tyb: regdnb is rmbit=0 & regdnb { export regdnb; }
526
559
Txb: -(reg9an) is rmbit=1 & reg9an { reg9an = reg9an-1; export *:1 reg9an; }
527
560
Txb: reg9dnb is rmbit=0 & reg9dnb { export reg9dnb; }
528
561
562
+ @ifndef CPU32
529
563
# Bit field parameters
530
564
f_off: fldoffdat is flddo=0 & fldoffdat { export *[const]:4 fldoffdat; }
531
565
f_off: fldoffreg is flddo=1 & fldoffreg { export fldoffreg; }
532
566
f_wd: fldwddat is flddw=0 & fldwddat { export *[const]:4 fldwddat; }
533
567
f_wd: fldwdreg is flddw=1 & fldwdreg { export fldwdreg; }
568
+ @endif # CPU32
534
569
535
570
rreg: regxdn is da=0 & regxdn { export regxdn; }
536
571
rreg: regxan is da=1 & regxan { export regxan; }
@@ -772,6 +807,7 @@ with : extGUARD=1 {
772
807
:bclr.l reg9dn,regdn is op=0 & reg9dn & op68=6 & mode=0 & regdn { mask:4 = 1<<(reg9dn&31); ZF=(regdn&mask)==0; regdn=regdn&(~mask); }
773
808
:bclr.l d8,regdn is opbig=8 & op67=2 & mode=0 & regdn; d8 { mask:4 = 1<<d8; ZF=(regdn&mask)==0; regdn=regdn&(~mask); }
774
809
810
+ @ifndef CPU32
775
811
:bfchg e2l{f_off:f_wd} is opbig=0xea & op67=3 & $(DAT_DIR_CTL_ADDR_MODES); f_off & f_wd; e2l [ savmod2=savmod1; regtsan=regtfan; ] {
776
812
logflags(); tmp:4 = e2l; getbitfield(tmp, f_off, f_wd); resbitflags(tmp, f_wd-1); mask:4 = 0; bfmask(mask, f_off, f_wd); e2l = (e2l & ~mask) | (~(e2l & mask) & mask);
777
813
}
@@ -826,6 +862,7 @@ define pcodeop countLeadingZeros;
826
862
:bftst e2l{f_off:f_wd} is opbig=0xe8 & op67=3 & $(DAT_DIR_CTL_ADDR_MODES); f_off & f_wd; e2l [ savmod2=savmod1; regtsan=regtfan; ] {
827
863
logflags(); tmp:4 = e2l; getbitfield(tmp, f_off, f_wd); resbitflags(tmp, f_wd-1);
828
864
}
865
+ @endif # CPU32
829
866
830
867
:bkpt "#"op02 is opbig=0x48 & op67=1 & op5=0 & op34=1 & op02 unimpl
831
868
@@ -847,6 +884,7 @@ define pcodeop countLeadingZeros;
847
884
:btst.l reg9dn,regdn is op=0 & reg9dn & op68=4 & mode=0 & regdn { mask:4 = 1<<(reg9dn&31); ZF=(regdn&mask)==0; }
848
885
:btst.l d8,regdn is opbig=8 & op67=0 & mode=0 & regdn; d8 { mask:4 = 1<<d8; ZF=(regdn&mask)==0; }
849
886
887
+ @ifndef CPU32
850
888
:callm "#"^d8,e2l is opbig=6 & op67=3 & $(CTL_ADDR_MODES); d8; e2l [ savmod2=savmod1; regtsan=regtfan; ] unimpl
851
889
852
890
#TODO: should constrain CAS to ignore mode=7 & regan=4 (place CAS2 before CAS to avoid problem)
@@ -914,6 +952,7 @@ define pcodeop countLeadingZeros;
914
952
ZF = 1;
915
953
NF = 0;
916
954
}
955
+ @endif # CPU32
917
956
918
957
:chk.w eaw,reg9dnw is (op=4 & reg9dnw & op68=6 & $(DAT_ALTER_ADDR_MODES))... & eaw unimpl
919
958
:chk.l eal,reg9dn is (op=4 & reg9dn & op68=4 & $(DAT_ALTER_ADDR_MODES))... & eal unimpl
@@ -969,11 +1008,16 @@ cachetype: "both" is op67=3 { export 3:4; }
969
1008
subflags(tmp2,tmp1); local tmp =tmp2-tmp1; resflags(tmp); }
970
1009
:cmpm.l (regan)+,(reg9an)+ is op=11 & reg9an & op8=1 & op67=2 & op5=0 & op34=1 & regan { local tmp1=*:4 regan; regan=regan+4; local tmp2=*:4 reg9an; reg9an=reg9an+4;
971
1010
subflags(tmp2,tmp1); local tmp =tmp2-tmp1; resflags(tmp); }
1011
+
1012
+ @ifndef CPU32
972
1013
# cpBcc # need to know specific copressors use copcc1
973
1014
# cpDBcc # use copcc2
974
1015
# cpGEN
1016
+ # cpRESTORE
1017
+ # cpSAVE
975
1018
# cpScc # use copcc2
976
1019
# cpTRAPcc # use copcc2
1020
+ @endif # CPU32
977
1021
978
1022
:db^cc regdnw,addr16 is op=5 & cc & op67=3 & op5=0 & op34=1 & regdnw; addr16 { if (cc) goto inst_next; regdnw=regdnw-1; if (regdnw!=-1) goto addr16; }
979
1023
@@ -1467,7 +1511,9 @@ macro negResFlags(result) {
1467
1511
:ori "#"^d8,"CCR" is opbig=0 & op37=7 & op02=4; d8 { packflags(SR); SR=SR|d8; unpackflags(SR); }
1468
1512
:ori "#"^d16,SR is SR; opbig=0x00 & d8base=0x7c; d16 { packflags(SR); SR=SR|d16; unpackflags(SR); }
1469
1513
1514
+ @ifndef CPU32
1470
1515
:pack Tyb,Txb,"#"d16 is op=8 & op48=20 & Txb & Tyb; d16 unimpl
1516
+ @endif # CPU32
1471
1517
1472
1518
:pea eaptr is (opbig=0x48 & op67=1 & $(CTL_ADDR_MODES))... & eaptr { SP = SP-4; *SP = eaptr; }
1473
1519
@@ -1605,8 +1651,10 @@ ptestLevel: "#"^mregn is mregn { export *[const]:1 mregn; }
1605
1651
:rtd "#"^d16 is opbig=0x4e & op37=14 & op02=4; d16 { PC = *SP; SP = SP + 4 + d16; return [PC]; }
1606
1652
:rte is d16=0x4e73 { tmp:4 = 0; return [tmp]; }
1607
1653
1654
+ @ifndef CPU32
1608
1655
:rtm regdn is opbig=0x06 & op37=24 & regdn unimpl
1609
1656
:rtm regan is opbig=0x06 & op37=25 & regan unimpl
1657
+ @endif # CPU32
1610
1658
1611
1659
:rtr is opbig=0x4e & op37=14 & op02=7 { SR = *SP; SP = SP+2; PC = *SP; SP = SP+4; unpackflags(SR); return [PC]; }
1612
1660
@@ -1617,7 +1665,16 @@ ptestLevel: "#"^mregn is mregn { export *[const]:1 mregn; }
1617
1665
1618
1666
:s^cc eab is (op=5 & cc & op67=3 & $(DAT_ALTER_ADDR_MODES))... & eab { eab = -cc; }
1619
1667
1620
- :stop "#"^d16 is opbig=0x4e & d8base=0x72; d16 unimpl
1668
+ #TODO: implement STOP
1669
+ :stop "#"^d16 is opbig=0x4e & d8base=0x72; d16 { SR = d16; }
1670
+
1671
+ @ifdef CPU32
1672
+ #TODO: implement interrupt mask → EBI; STOP
1673
+ :lpstop "#"^d16 is opbig=0xf8 & d8base=0x00; opbig=0x01 & d8base=0xC0; d16 { SR = d16; }
1674
+
1675
+ #TODO: implement: if (background mode enabled) then enter Background Mode else Format/Vector offset → –(SSP); PC → –(SSP); SR → –(SSP); (Vector) → PC
1676
+ :bgnd is opbig=0x4A & d8base=0xFA { }
1677
+ @endif # CPU32
1621
1678
1622
1679
:sub.b eab,reg9dnb is (op=9 & reg9dnb & op68=0)... & eab
1623
1680
{ subflags(reg9dnb, eab); reg9dnb = reg9dnb - eab; resflags(reg9dnb); }
@@ -1680,6 +1737,96 @@ ptestLevel: "#"^mregn is mregn { export *[const]:1 mregn; }
1680
1737
:tas eab is (opbig=0x4a & op67=3 & $(DAT_ALTER_ADDR_MODES))... & eab { logflags(); resflags(eab); eab = eab | 0x80; }
1681
1738
@endif # COLDFIRE
1682
1739
1740
+ @ifdef CPU32
1741
+
1742
+ # TODO: tbl_mode=4 and tbl_mode=5 constructors
1743
+
1744
+ tbl_eal: (tbl_regan) is tbl_mode=2 & tbl_regan { export *:4 tbl_regan; }
1745
+ # tbl_eal: -(tbl_regan) is tbl_mode=4 & tbl_regan { tbl_regan = tbl_regan - 4; export *:4 tbl_regan; }
1746
+ # tbl_eal: (d16,tbl_regan) is tbl_mode=5 & tbl_regan; d16 { local tmp = tbl_regan + d16; export *:4 tmp; }
1747
+ tbl_eal: (extw) is tbl_mode=6 & tbl_regan; extw [ regtfan = tbl_regan; pcmode = 0; ] { build extw; export *:4 extw; }
1748
+ tbl_eal: (d16,PC) is PC & tbl_mode=7 & tbl_regan=2; d16 { tmp:4 = inst_start + 2 + d16; export *:4 tmp; }
1749
+ tbl_eal: (extw) is tbl_mode=7 & tbl_regan=3; extw [ pcmode=1; ] { build extw; export *:4 extw; }
1750
+ tbl_eal: (d16)".w" is tbl_mode=7 & tbl_regan=0; d16 { export *:4 d16; }
1751
+ tbl_eal: (d32)".l" is tbl_mode=7 & tbl_regan=1; d32 { export *:4 d32; }
1752
+ tbl_eal: "#"^d32 is tbl_mode=7 & tbl_regan=4; d32 { export *[const]:4 d32; }
1753
+
1754
+ tbl_eaw: (tbl_regan) is tbl_mode=2 & tbl_regan { export *:2 tbl_regan; }
1755
+ # tbl_eaw: -(tbl_regan) is tbl_mode=4 & tbl_regan { tbl_regan = tbl_regan - 2; export *:2 tbl_regan; }
1756
+ # tbl_eaw: (d16,tbl_regan) is tbl_mode=5 & tbl_regan; d16 { local tmp = tbl_regan + d16; export *:2 tmp; }
1757
+ tbl_eaw: (extw) is tbl_mode=6 & tbl_regan; extw [ pcmode=0; regtfan=tbl_regan; ] { build extw; export *:2 extw; }
1758
+ tbl_eaw: (d16,PC) is PC & tbl_mode=7 & tbl_regan=2; d16 { tmp:4 = inst_start + 2 + d16; export *:2 tmp; }
1759
+ tbl_eaw: (extw) is tbl_mode=7 & tbl_regan=3; extw [ pcmode=1; ] { build extw; export *:2 extw; }
1760
+ tbl_eaw: (d16)".w" is tbl_mode=7 & tbl_regan=0; d16 { export *:2 d16; }
1761
+ tbl_eaw: (d32)".l" is tbl_mode=7 & tbl_regan=1; d32 { export *:2 d32; }
1762
+ tbl_eaw: "#"^d16 is tbl_mode=7 & tbl_regan=4; d16 { export *[const]:2 d16; }
1763
+
1764
+ tbl_eab: (tbl_regan) is tbl_mode=2 & tbl_regan { export *:1 tbl_regan; }
1765
+ # tbl_eab: -(tbl_regan) is tbl_mode=4 & tbl_regan { tbl_regan = tbl_regan - 1; export *:1 tbl_regan; }
1766
+ # tbl_eab: (d16,tbl_regan) is tbl_mode=5 & tbl_regan; d16 { local tmp = tbl_regan + d16; export *:1 tmp; }
1767
+ tbl_eab: (extw) is tbl_mode=6 & tbl_regan; extw [ pcmode=0; regtfan=tbl_regan; ] { build extw; export *:1 extw; }
1768
+ tbl_eab: (d16,PC) is PC & tbl_mode=7 & tbl_regan=2; d16 { tmp:4 = inst_start + 2 + d16; export *:1 tmp; }
1769
+ tbl_eab: (extw) is tbl_mode=7 & tbl_regan=3; extw [ pcmode=1; ] { build extw; export *:1 extw; }
1770
+ tbl_eab: (d16)".w" is tbl_mode=7 & tbl_regan=0; d16 { export *:1 d16; }
1771
+ tbl_eab: (d32)".l" is tbl_mode=7 & tbl_regan=1; d32 { export *:1 d32; }
1772
+ tbl_eab: "#"^d8 is tbl_mode=7 & tbl_regan=4; d8 { export *[const]:1 d8; }
1773
+
1774
+ tblsign: "u" is tbl_sign=0 { }
1775
+ tblsign: "s" is tbl_sign=1 { }
1776
+
1777
+ tbldrsign: "u" is tbl_dr_sign=0 { }
1778
+ tbldrsign: "s" is tbl_dr_sign=1 { }
1779
+
1780
+ define pcodeop tableLookup;
1781
+
1782
+ # Rounded Table Lookup and Interpolate
1783
+
1784
+ :tbl^tblsign^".b" tbl_eab,tbl_regxdn is (tbl_opbig=0xF8 & tbl_op67=0 & $(TBL_ADDR_MODES) & tbl_size=0 & tblsign & tbl_round=0 & tbl_regxdn) ... & tbl_eab
1785
+ { tbl_regxdn = tableLookup(tbl_regxdn, tbl_eab); }
1786
+
1787
+ :tbl^tblsign^".w" tbl_eaw,tbl_regxdn is (tbl_opbig=0xF8 & tbl_op67=0 & $(TBL_ADDR_MODES) & tbl_size=1 & tblsign & tbl_round=0 & tbl_regxdn) ... & tbl_eaw
1788
+ { tbl_regxdn = tableLookup(tbl_regxdn, tbl_eaw); }
1789
+
1790
+ :tbl^tblsign^".l" tbl_eal,tbl_regxdn is (tbl_opbig=0xF8 & tbl_op67=0 & $(TBL_ADDR_MODES) & tbl_size=2 & tblsign & tbl_round=0 & tbl_regxdn) ... & tbl_eal
1791
+ { tbl_regxdn = tableLookup(tbl_regxdn, tbl_eal); }
1792
+
1793
+ # Unrounded Table Lookup and Interpolate
1794
+
1795
+ :tbl^tblsign^"n.b" tbl_eab,tbl_regxdn is (tbl_opbig=0xF8 & tbl_op67=0 & $(TBL_ADDR_MODES) & tbl_size=0 & tblsign & tbl_round=1 & tbl_regxdn) ... & tbl_eab
1796
+ { tbl_regxdn = tableLookup(tbl_regxdn, tbl_eab); }
1797
+
1798
+ :tbl^tblsign^"n.w" tbl_eaw,tbl_regxdn is (tbl_opbig=0xF8 & tbl_op67=0 & $(TBL_ADDR_MODES) & tbl_size=1 & tblsign & tbl_round=1 & tbl_regxdn) ... & tbl_eaw
1799
+ { tbl_regxdn = tableLookup(tbl_regxdn, tbl_eaw); }
1800
+
1801
+ :tbl^tblsign^"n.l" tbl_eal,tbl_regxdn is (tbl_opbig=0xF8 & tbl_op67=0 & $(TBL_ADDR_MODES) & tbl_size=2 & tblsign & tbl_round=1 & tbl_regxdn) ... & tbl_eal
1802
+ { tbl_regxdn = tableLookup(tbl_regxdn, tbl_eal); }
1803
+
1804
+ define pcodeop interpolate;
1805
+
1806
+ # Rounded Data Register Interpolate
1807
+
1808
+ :tbl^tbldrsign^".b" regdn:tbl_dr_reg,regxdn is opbig=0xF8 & op37=0 & mode=0 & regdn ; tbl_dr_size=0 & tbldrsign & tbl_dr_round=0 & tbl_dr_reg & regxdn
1809
+ { regxdn = interpolate(regdn, tbl_dr_reg); }
1810
+
1811
+ :tbl^tbldrsign^".w" regdn:tbl_dr_reg,regxdn is opbig=0xF8 & op37=0 & mode=0 & regdn ; tbl_dr_size=1 & tbldrsign & tbl_dr_round=0 & tbl_dr_reg & regxdn
1812
+ { regxdn = interpolate(regdn, tbl_dr_reg); }
1813
+
1814
+ :tbl^tbldrsign^".l" regdn:tbl_dr_reg,regxdn is opbig=0xF8 & op37=0 & mode=0 & regdn ; tbl_dr_size=2 & tbldrsign & tbl_dr_round=0 & tbl_dr_reg & regxdn
1815
+ { regxdn = interpolate(regdn, tbl_dr_reg); }
1816
+
1817
+ # Unrounded Data Register Interpolate
1818
+
1819
+ :tbl^tbldrsign^"n.b" regdn:tbl_dr_reg,regxdn is opbig=0xF8 & op37=0 & mode=0 & regdn ; tbl_dr_size=0 & tbldrsign & tbl_dr_round=1 & tbl_dr_reg & regxdn
1820
+ { regxdn = interpolate(regdn, tbl_dr_reg); }
1821
+
1822
+ :tbl^tbldrsign^"n.w" regdn:tbl_dr_reg,regxdn is opbig=0xF8 & op37=0 & mode=0 & regdn ; tbl_dr_size=1 & tbldrsign & tbl_dr_round=1 & tbl_dr_reg & regxdn
1823
+ { regxdn = interpolate(regdn, tbl_dr_reg); }
1824
+
1825
+ :tbl^tbldrsign^"n.l" regdn:tbl_dr_reg,regxdn is opbig=0xF8 & op37=0 & mode=0 & regdn ; tbl_dr_size=2 & tbldrsign & tbl_dr_round=1 & tbl_dr_reg & regxdn
1826
+ { regxdn = interpolate(regdn, tbl_dr_reg); }
1827
+
1828
+ @endif # CPU32
1829
+
1683
1830
:trap "#"^op03 is opbig=0x4e & op67=1 & op45=0 & op03 { vector:1 = op03; __m68k_trap(vector); }
1684
1831
:trap^cc is op=5 & cc & op37=31 & op02=4 { if (!cc) goto inst_next; SP = SP - 4; *:4 SP = PC; vector:1 = 7; __m68k_trap(vector); }
1685
1832
:trap^cc^".w" "#"^d16 is op=5 & cc & op37=31 & op02=2; d16 { if (!cc) goto inst_next; SP = SP - 4; *:4 SP = PC; __m68k_trapv(); }
@@ -1696,7 +1843,9 @@ ptestLevel: "#"^mregn is mregn { export *[const]:1 mregn; }
1696
1843
1697
1844
:unlk regan is opbig=0x4e & op37=11 & regan { SP = regan; regan = *SP; SP = SP+4; }
1698
1845
1846
+ @ifndef CPU32
1699
1847
:unpk Tyb,Txb,"#"^d16 is op=8 & Txb & op48=24 & Tyb; d16 unimpl
1848
+ @endif # CPU32
1700
1849
1701
1850
# Floating Point Instructions
1702
1851
0 commit comments