|
|
1.1 root 1: //
2: // nono
1.1.1.2 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #pragma once
8:
1.1.1.15 root 9: #include "nono.h"
1.1.1.12 root 10:
1.1.1.14 root 11: // 定数。
12: struct M88100
1.1 root 13: {
14: // PID(cr0)
1.1.1.15 root 15: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
16: // +---------------+---------------+---------------+-------------+-+
17: // | 0 | REV | VER |M|
18: // +---------------+---------------+---------------+-------------+-+
1.1 root 19: static const uint32 PID_REV_MASK = 0x0000ff00; // 0 = MC88100
20: static const uint32 PID_VER_MASK = 0x000000fe;
21: static const uint32 PID_MASTER = 0x00000001;
1.1.1.15 root 22:
1.1 root 23: // PSR(cr1)
1.1.1.15 root 24: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25: // +-+-+-+-+-------+---------------+---------------+-------+-+-+-+-+
26: // |S|B|S|C| |D|M|I|S|
27: // |U|O|E| | 0 |1|X|N|F|
28: // +-+-+-+-+-------+---------------+---------------+-------+-+-+-+-+
1.1 root 29: static const uint32 PSR_SUPER = 0x80000000;
30: static const uint32 PSR_BO_LE = 0x40000000; // ByteOrder(Little)
31: static const uint32 PSR_SER = 0x20000000;
32: static const uint32 PSR_C = 0x10000000; // Carry
33: static const uint32 PSR_SFD1 = 0x00000008; // SFU1 Disable
34: static const uint32 PSR_MXM = 0x00000004; // MisalignedAccessEnable
35: static const uint32 PSR_IND = 0x00000002; // Interrupt Disable
36: static const uint32 PSR_SFRZ = 0x00000001; // Shadow Freeze
37:
38: // 例外処理で使用される S*IP
1.1.1.15 root 39: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
40: // +---------------+---------------+---------------+-----------+-+-+
41: // | S*IP |V|E|
42: // +---------------+---------------+---------------+-----------+-+-+
1.1 root 43: static const uint32 SIP_MASK = 0xfffffffcU;
44: static const uint32 SIP_V = 0x00000002;
45: static const uint32 SIP_E = 0x00000001;
46:
47: // DMTn、データ例外
1.1.1.15 root 48: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
49: // +---------------+---------------+-+-+-+-+-------+-+-+-+-+-+-+-+-+
50: // | |B|D|D|L| |S|E|E|E|E|W|V|
51: // | 0 |O|A|B|K| DREG | |3|2|1|0|R| |
52: // +---------------+---------------+-+-+-+-+-------+-+-+-+-+-+-+-+-+
1.1 root 53: static const uint32 DM_BO = 0x00008000;
54: static const uint32 DM_DAS = 0x00004000;
55: static const uint32 DM_DOUB1 = 0x00002000;
56: static const uint32 DM_LOCK = 0x00001000;
57: static const uint32 DM_DREG_MASK = 0x00000f80;
58: static const uint32 DM_SIGNED = 0x00000040;
59: static const uint32 DM_EN3 = 0x00000020;
60: static const uint32 DM_EN2 = 0x00000010;
61: static const uint32 DM_EN1 = 0x00000008;
62: static const uint32 DM_EN0 = 0x00000004;
63: static const uint32 DM_EN_MASK = (DM_EN0 | DM_EN1 | DM_EN2 | DM_EN3);
64: static const uint32 DM_WRITE = 0x00000002;
65: static const uint32 DM_VALID = 0x00000001;
66: // 内部識別フラグ
67: static const uint32 DM_SIZE_B = (1U << 16) | DM_EN3;
68: static const uint32 DM_SIZE_H = (1U << 17) | DM_EN3 | DM_EN2;
69: static const uint32 DM_SIZE_W = (1U << 18) | DM_EN_MASK;
70: static const uint32 DM_USR = (1U << 20);
71: static const uint32 DM_BU = DM_SIZE_B;
72: static const uint32 DM_B = DM_SIZE_B | DM_SIGNED;
73: static const uint32 DM_HU = DM_SIZE_H;
74: static const uint32 DM_H = DM_SIZE_H | DM_SIGNED;
75: static const uint32 DM_W = DM_SIZE_W;
76: static const uint32 DM_D1 = DM_SIZE_W | DM_DOUB1;
77: static const uint32 DM_D2 = DM_SIZE_W;
78:
1.1.1.11 root 79: // FPECR(fcr0)
80: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
81: // +---------------+---------------+---------------+-+-+-+-+-+-+-+-+
82: // | |I|U|P|O|D|U|O|I|
83: // | 0 |O|N|V|P|Z|F|V|N|
84: // +---------------+---------------+---------------+-+-+-+-+-+-+-+-+
85: static const uint32 FPECR_MASK = 0x000000ff; // 有効ビットマスク
86: static const uint32 FPECR_FIOV = 0x00000080; // FP Integer Overflow
87: static const uint32 FPECR_FUNIMP= 0x00000040; // FP Unimplemented
88: static const uint32 FPECR_FPRV = 0x00000020; // FP Privilege Violation
89: static const uint32 FPECR_FROP = 0x00000010; // FP Reserved Operand
90: static const uint32 FPECR_FDVZ = 0x00000008; // FP Divice-by-Zero
91: static const uint32 FPECR_FUNF = 0x00000004; // FP Underflow
92: static const uint32 FPECR_FOVF = 0x00000002; // FP Overflow
93: static const uint32 FPECR_FINX = 0x00000001; // FP Inexact
94:
95: // FPHS1(fcr1)
96: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
97: // +-+---------------------+---------------------------------------+
98: // |S| Exponent | High order 20 bits of Mantissa |
99: // +-+---------------------+---------------------------------------+
100:
101: // FPLS1(fcr2)
102: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
103: // +---------------------------------------------------------------+
104: // | Low order bits of Mantissa or Integer Operand |
105: // +---------------------------------------------------------------+
106:
107: // FPHS2(fcr3)
108: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
109: // +-+---------------------+---------------------------------------+
110: // |S| Exponent | High order 20 bits of Mantissa |
111: // +-+---------------------+---------------------------------------+
112:
113: // FPLS2(fcr4)
114: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
115: // +---------------------------------------------------------------+
116: // | Low order bits of Mantissa or Integer Operand |
117: // +---------------------------------------------------------------+
118:
119: // FPPT(fcr5)
120: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
121: // +---------------+---------------+---------+---+---+---+---------+
122: // | 0 | OPCODE |T1 |T2 |TD | DestReg |
123: // +---------------+---------------+---------+---+---+---+---------+
124: static const uint32 FPPT_MASK = 0x0000ffff; // 有効ビットマスク
125: static const uint32 FPPT_OPCODE = 0x0000f800; // Opcode
126: static const uint32 FPPT_T1 = 0x00000600; // Source1 Operand Size
127: static const uint32 FPPT_T2 = 0x00000180; // Source2 Operand Size
128: static const uint32 FPPT_TD = 0x00000060; // Destination Size
129: static const uint32 FPPT_DEST = 0x0000001f; // Destination Register No.
130:
131: // FPRH(fcr6)
132: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
133: // +-----+-+-+-+-+-+-----+---------+-------------+-----------------+
134: // |S|RM |G|R|S|A| 0 | High Order Bits of Mantissa |
135: // +-----+-+-+-+-+-+-----+---------+-------------+-----------------+
136: static const uint32 FPRH_MASK = 0xfe1fffff; // 有効ビットマスク
137: static const uint32 FPRH_SIGN = 0x80000000; // Result Sign
138: static const uint32 FPRH_RNDMODE= 0x60000000; // Rounding Mode for Res.
139: static const uint32 FPRH_GUARD = 0x10000000; // Guard Bit for Result
140: static const uint32 FPRH_ROUND = 0x08000000; // Round Bit for Result
141: static const uint32 FPRH_STICKY = 0x04000000; // Sticky Bit for Result
142: static const uint32 FPRH_ADDONE = 0x02000000; // Add One
143: static const uint32 FPRH_MANT = 0x001fffff; // Mantissa(High)
144: static const uint32 FPRH_1 = 0x00100000; // 隠し実数部の 1
145:
146: // FPRL(fcr7)
147: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
148: // +---------------------------------------------------------------+
149: // | Low Order Bits of Mantissa |
150: // +---------------------------------------------------------------+
151:
152: // FPIT(fcr8)
153: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
154: // +-----------------------+-------+---------+-+-+-+-+-+-+---------+
155: // | | | |D|E|E|E|E|E| |
156: // | RESEXP (12bits) | 0 | OPCODE |S|V|Z|U|O|N| DestReg |
157: // +-----------------------+-------+---------+-+-+-+-+-+-+---------+
158: static const uint32 FPIT_MASK = 0xfff0ffff; // 有効ビットマスク
159: static const uint32 FPIT_RESEXP = 0xfff00000; // Result Exponent
160: static const uint32 FPIT_OPCODE = 0x0000f800; // Opcode
161: static const uint32 FPIT_DESTSIZ= 0x00000400; // Destination Size
162: static const uint32 FPIT_EFINV = 0x00000200; // Enable Invalid Op.
163: static const uint32 FPIT_EFDVZ = 0x00000100; // Enable Divide-by-Zero
164: static const uint32 FPIT_EFUNF = 0x00000080; // Enable Underflow
165: static const uint32 FPIT_EFOVF = 0x00000040; // Enable Overflow
166: static const uint32 FPIT_EFINX = 0x00000020; // Enable Inexact
167: static const uint32 FPIT_DEST = 0x0000001f; // Destination Register No.
168:
169: // FPSR(fcr62)
170: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
171: // +---------------+---------------+---------------+-----+-+-+-+-+-+
172: // | |A|A|A|A|A|
173: // | 0 |V|D|U|O|I|
174: // +---------------+---------------+---------------+-----+-+-+-+-+-+
175: static const uint32 FPSR_MASK = 0x0000001f; // 有効ビットマスク
176: static const uint32 FPSR_AFINV = 0x00000010; // Acc. Invalid Op. Flag
177: static const uint32 FPSR_AFDVZ = 0x00000008; // Acc. Divide-by-Zero Flag
178: static const uint32 FPSR_AFUNF = 0x00000004; // Acc. Underflow Flag
179: static const uint32 FPSR_AFOVF = 0x00000002; // Acc. Overflow Flag
180: static const uint32 FPSR_AFINX = 0x00000001; // Acc. Inexact Flag
181:
182: // FPCR(fcr63)
183: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
184: // +---------------+---------------+---+-----------+-----+-+-+-+-+-+
185: // | | | |E|E|E|E|E|
186: // | 0 |RM | |V|D|U|O|I|
187: // +---------------+---------------+---+-----------+-----+-+-+-+-+-+
188: static const uint32 FPCR_MASK = 0x0000c01f; // 有効ビットマスク
189: static const uint32 FPCR_RM = 0x0000c000; // Rounding Mask
190: static const uint32 FPCR_EFINV = 0x00000010; // Enable Invalid Operation
191: static const uint32 FPCR_EFDVZ = 0x00000008; // Enable Divide-by-Zero
192: static const uint32 FPCR_EFUNF = 0x00000004; // Enable Underflow
193: static const uint32 FPCR_EFOVF = 0x00000002; // Enable Overflow
194: static const uint32 FPCR_EFINX = 0x00000001; // Enable Inexact
195:
1.1.1.16! root 196: // 例外ベクタ。
! 197: static const uint32 EXCVEC_RESET = 0;
! 198: static const uint32 EXCVEC_INTERRUPT = 1;
! 199: static const uint32 EXCVEC_INST = 2;
! 200: static const uint32 EXCVEC_DATA = 3;
! 201: static const uint32 EXCVEC_MISALIGNED = 4;
! 202: static const uint32 EXCVEC_UNIMPL_OP = 5;
! 203: static const uint32 EXCVEC_PRIV = 6;
! 204: static const uint32 EXCVEC_BOUNDS = 7;
! 205: static const uint32 EXCVEC_INT_DIV = 8;
! 206: static const uint32 EXCVEC_INT_OVF = 9;
! 207: static const uint32 EXCVEC_ERROR = 10;
! 208: static const uint32 EXCVEC_SFU1_PRECISE = 114;
! 209: static const uint32 EXCVEC_SFU1_IMPRECISE = 115;
! 210: static const uint32 EXCVEC_SFU2_PRECISE = 116;
! 211: static const uint32 EXCVEC_SFU3_PRECISE = 118;
! 212: static const uint32 EXCVEC_SFU4_PRECISE = 120;
! 213: static const uint32 EXCVEC_SFU5_PRECISE = 122;
! 214: static const uint32 EXCVEC_SFU6_PRECISE = 124;
! 215: static const uint32 EXCVEC_SFU7_PRECISE = 126;
! 216:
! 217: // 例外の優先順位 (LSB 側が優先度高)。一部カテゴリ分けも兼ねる。
! 218: //
! 219: // 優先度 例外
! 220: // 1 RESET
! 221: // 1 (ERROR)
! 222: // 2 INST
! 223: // 3 UNIMPL_OP
! 224: // 4 PRIV
! 225: // 5 INTERNAL … 内部発生例外のうちトラップ以外
! 226: // 5 TRAP … 内部発生例外のうちトラップのみ
! 227: // -- (OUTER) …これ以降のどれかが立っているという代表ビット
! 228: // 6 INTERRUPT
! 229: // 7 SFU_IMPRECISE
! 230: // 8 DATA
! 231: //
! 232: // ERROR 例外は Table. 6-2 には載ってないけど、実質ダブルバスフォールト
! 233: // なので、リセットに準じる高さの気がする…。
! 234: // TRAP は他の内部発生例外 (INTERNAL) とは区別が必要なので分けてある。
! 235: // INTERNAL と TRAP はこの優先度だけでなくベクタ情報も必要。
! 236: // INTERRUPT と DATA はどちらが起きても同時に処理するので、
! 237: // どちらかを立てたまま OUTER ビットで処理させる。
! 238: // SFU_IMPRECISE は未調査。
! 239: static const uint32 EXCPRI_RESET = (1U << 0);
! 240: static const uint32 EXCPRI_ERROR = (1U << 1);
! 241: static const uint32 EXCPRI_INST = (1U << 2);
! 242: static const uint32 EXCPRI_UNIMPL_OP = (1U << 3);
! 243: static const uint32 EXCPRI_PRIV = (1U << 4);
! 244: static const uint32 EXCPRI_INTERNAL = (1U << 5);
! 245: static const uint32 EXCPRI_TRAP = (1U << 6);
! 246: static const uint32 EXCPRI_OUTER = (1U << 7);
! 247: static const uint32 EXCPRI_INTERRUPT = (1U << 8);
! 248: static const uint32 EXCPRI_SFU_IMPRECISE = (1U << 9);
! 249: static const uint32 EXCPRI_DATA = (1U << 10);
! 250: static const uint32 EXCPRI_OUTER_MASK =
! 251: EXCPRI_INTERRUPT | EXCPRI_SFU_IMPRECISE | EXCPRI_DATA;
1.1.1.14 root 252:
253: // 32bit 命令コードからディスパッチ用の 12bit に変換。
254: // ops と disasm で使うため。
255: static uint32 op32_to_12(uint32 op) {
256: return ((op >> 20) & 0x0fc0) | ((op >> 10) & 0x003f);
257: }
258: };
259:
260: // m88100 レジスタイメージを保持する構造体。
261: // この構造体はコピーや比較をするので、ポインタとかは置かないこと。
262: struct m88100reg
263: {
1.1 root 264: // 頻繁にアクセスしそうな変数はオフセットの若いほうに持ってきておく。
265:
266: // 実行中の命令
1.1.1.14 root 267: uint64 opX {};
1.1 root 268: // プリフェッチ命令
1.1.1.14 root 269: uint64 opF {};
1.1 root 270:
1.1.1.14 root 271: uint32 xip {};
272: uint32 nip {};
273: uint32 fip {};
1.1 root 274:
275: uint32 r[32] {};
276: union {
277: uint32 cr[21] {};
278: struct {
1.1.1.16! root 279: uint32 pid; // cr0 (ReadOnly)
1.1 root 280: uint32 psr; // cr1
281: uint32 epsr; // cr2
282: uint32 ssbr; // cr3
1.1.1.16! root 283: uint32 sxip; // cr4 (ReadOnly)
1.1 root 284: uint32 snip; // cr5
285: uint32 sfip; // cr6
286: uint32 vbr; // cr7
287: uint32 dmt0; // cr8
288: uint32 dmd0; // cr9
289: uint32 dma0; // cr10
290: uint32 dmt1; // cr11
291: uint32 dmd1; // cr12
292: uint32 dma1; // cr13
293: uint32 dmt2; // cr14
294: uint32 dmd2; // cr15
295: uint32 dma2; // cr16
296: uint32 sr[4]; // cr17,18,19,20
297: };
298: };
299: union {
300: uint32 fcr[11] {};
301: struct {
302: uint32 fpecr; // fcr0
303: uint32 fphs1; // fcr1
304: uint32 fpls1; // fcr2
305: uint32 fphs2; // fcr3
306: uint32 fpls2; // fcr4
307: uint32 fppt; // fcr5
308: uint32 fprh; // fcr6
309: uint32 fprl; // fcr7
310: uint32 fpit; // fcr8
311: uint32 fpsr; // fcr62 [9]
312: uint32 fpcr; // fcr63 [10]
313: };
314: };
315:
1.1.1.11 root 316: static const uint32 fcr_mask[11];
1.1 root 317: static const char * const sipname[3];
1.1.1.2 root 318: static const char * const dmt_en_str[16];
1.1 root 319: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.