-
Notifications
You must be signed in to change notification settings - Fork 0
/
Cpu.h
137 lines (122 loc) · 2.71 KB
/
Cpu.h
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#ifndef __VIRTGBA_CPU_H
#define __VIRTGBA_CPU_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "Memory.h"
#include "AsmTranslator.h"
using namespace llvm;
class CPU {
friend class AsmTranslator;
public:
using DecodeStatus = MCDisassembler::DecodeStatus;
enum CPUMode {
ARM = 0,
THUMB = 1,
};
CPU();
void execute();
int getInstrWidth() { return InstrWidth; }
void setMem(Memory *M) { Mem = M; }
template<typename T>
void StoreToMemory(uint32_t Addr, T Val) {
*((T *)Mem->getPointer(Addr)) = Val;
}
void switchMode(CPUMode M) {
Mode = M;
InstrWidth = getARMOrThumb(4, 2);
if (M == CPUMode::ARM) {
CPSR &= ~(1 << 5);
} else {
CPSR |= (1 << 5);
}
};
enum PrivMode {
Normal = 0,
FIQ,
SVC,
ABT,
IRQ,
UND,
};
enum Register {
R0 = 0,
R1,
R2,
R3,
R4,
R5,
R6,
R7,
R8,
R9,
R10,
R11,
R12,
R13, // SP
R14, // LR
R8_FIQ,
R9_FIQ,
R10_FIQ,
R11_FIQ,
R12_FIQ,
R13_FIQ,
R13_SVC,
R13_ABT,
R13_IRQ,
R13_UND,
R14_FIQ,
R14_SVC,
R14_ABT,
R14_IRQ,
R14_UND,
PC,
RegCount,
};
private:
DecodeStatus InstrFetch(MCInst &, uint32_t &);
void printInst(MCInst &, uint64_t);
DecodeStatus disassemble(ArrayRef<uint8_t>, MCInst &);
PrivMode getPrivMode() { return PrivM; }
template<typename T>
T getARMOrThumb(T Arm, T Thumb) {
return Mode == CPUMode::ARM ? Arm : Thumb;
}
void setPC(uint32_t pc) { GPR[Register::PC] = pc; }
uint32_t getPC() { return GPR[Register::PC]; }
uint32_t getIFProgCounter() { return getPC(); }
uint32_t getEXProgCounter() { return getPC() + InstrWidth; }
void addOffsetToPC(uint32_t Offset) { GPR[Register::PC] += Offset; }
void advancePCtoNext() { addOffsetToPC(InstrWidth); }
PrivMode PrivM;
// General Purpose Register
uint32_t GPR[Register::RegCount];
// Control and Status Register
uint32_t CPSR;
uint32_t SPSR[6];
CPUMode Mode;
Memory *Mem;
int InstrWidth;
MCRegisterInfo *MRI;
MCAsmInfo *AsmInfo;
MCInstrInfo *MII;
MCDisassembler *ARMDisAsm;
MCDisassembler *ThumbDisAsm;
MCInstPrinter *IP;
const MCSubtargetInfo *ARMSTI;
const MCSubtargetInfo *ThumbSTI;
};
#endif