-
Notifications
You must be signed in to change notification settings - Fork 0
/
cop0.cpp
111 lines (98 loc) · 2.14 KB
/
cop0.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// ============================================================================
// Portable MIPS III emulator
//
// Marcos Medeiros
// ============================================================================
#include <iostream>
#include <cstdint>
#include "mips3.h"
#include "mipsdef.h"
#include "memory.h"
namespace mips
{
const char *mips3::cop0_reg_names[32] = {
"Index", "Random", "EntryLo0", "EntryLo1", "Context",
"PageMask", "Wired", "--", "BadVAddr", "Count", "EntryHi",
"Compare", "SR", "Cause", "EPC", "PRId", "Config", "LLAddr",
"WatchLo", "WatchHi", "XContext", "--", "--", "--", "--","--",
"ECC", "CacheErr", "TagLo", "TagHi", "ErrorEPC", "--"
};
enum {
INDEX = 0,
RANDOM,
ENTRYLO0,
ENTRYLO1,
CONTEXT,
PAGEMASK,
WIRED,
__COP0_UNUSED0,
BADVADDR,
COUNT,
ENTRYHI,
COMPARE,
SR,
CAUSE,
EPC,
PRId,
CONFIG,
LLADDR,
WATCHLO,
WATCHHI,
XCONTEXT,
__COP0_UNUSED1,
__COP0_UNUSED2,
__COP0_UNUSED3,
__COP0_UNUSED4,
__COP0_UNUSED5,
ECC,
CACHEERR,
TAGLO,
TAGHI,
ERROREPC
} ;
#define COP0_R(x) m_state.cpr[0][x]
void mips3::tlb_init()
{
m_tlb = new tlb_entry[m_tlb_entries];
}
void mips3::tlb_flush()
{
for (int i = 0; i < m_tlb_entries; i++) {
m_tlb[i].v[0] = 0;
m_tlb[i].v[1] = 0;
}
}
void mips3::cop0_execute(uint32_t opcode)
{
switch (RSNUM) {
// MFC
case 0x00:
RT = COP0_R(RDNUM & 0x1F);
break;
// MTC
case 0x04:
m_state.cpr[0][RDNUM] = RT;
break;
// TLBWI
case 0x10: {
unsigned char idx = COP0_R(INDEX);
if (idx >= 48) {
cout << "TLBWI index > 48" << endl;
return;
}
tlb_entry *e = &m_tlb[idx];
e->v[1] = (COP0_R(ENTRYHI) & ~COP0_R(PAGEMASK & 0xFFFFFFFF)) | (COP0_R(PAGEMASK) << (32 + 13));
e->v[0] = (COP0_R(ENTRYLO1) << 32) | (COP0_R(ENTRYLO0) & 0xFFFFFFFF);
break;
}
default:
cout << "Op: " << RSNUM << " [COP0]" << endl;
break;
}
}
void mips3::cop0_reset()
{
for (int i = 0; i < 32; i++)
m_state.cpr[0][i] = 0;
}
}