smallworld-re 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- smallworld/__init__.py +35 -0
- smallworld/analyses/__init__.py +14 -0
- smallworld/analyses/analysis.py +88 -0
- smallworld/analyses/code_coverage.py +31 -0
- smallworld/analyses/colorizer.py +682 -0
- smallworld/analyses/colorizer_summary.py +100 -0
- smallworld/analyses/field_detection/__init__.py +14 -0
- smallworld/analyses/field_detection/field_analysis.py +536 -0
- smallworld/analyses/field_detection/guards.py +26 -0
- smallworld/analyses/field_detection/hints.py +133 -0
- smallworld/analyses/field_detection/malloc.py +211 -0
- smallworld/analyses/forced_exec/__init__.py +3 -0
- smallworld/analyses/forced_exec/forced_exec.py +87 -0
- smallworld/analyses/underlays/__init__.py +4 -0
- smallworld/analyses/underlays/basic.py +13 -0
- smallworld/analyses/underlays/underlay.py +31 -0
- smallworld/analyses/unstable/__init__.py +4 -0
- smallworld/analyses/unstable/angr/__init__.py +0 -0
- smallworld/analyses/unstable/angr/base.py +12 -0
- smallworld/analyses/unstable/angr/divergence.py +274 -0
- smallworld/analyses/unstable/angr/model.py +383 -0
- smallworld/analyses/unstable/angr/nwbt.py +63 -0
- smallworld/analyses/unstable/angr/typedefs.py +170 -0
- smallworld/analyses/unstable/angr/utils.py +25 -0
- smallworld/analyses/unstable/angr/visitor.py +315 -0
- smallworld/analyses/unstable/angr_nwbt.py +106 -0
- smallworld/analyses/unstable/code_coverage.py +54 -0
- smallworld/analyses/unstable/code_reachable.py +44 -0
- smallworld/analyses/unstable/control_flow_tracer.py +71 -0
- smallworld/analyses/unstable/pointer_finder.py +90 -0
- smallworld/arch/__init__.py +0 -0
- smallworld/arch/aarch64_arch.py +286 -0
- smallworld/arch/amd64_arch.py +86 -0
- smallworld/arch/i386_arch.py +44 -0
- smallworld/emulators/__init__.py +14 -0
- smallworld/emulators/angr/__init__.py +7 -0
- smallworld/emulators/angr/angr.py +1652 -0
- smallworld/emulators/angr/default.py +15 -0
- smallworld/emulators/angr/exceptions.py +7 -0
- smallworld/emulators/angr/exploration/__init__.py +9 -0
- smallworld/emulators/angr/exploration/bounds.py +27 -0
- smallworld/emulators/angr/exploration/default.py +17 -0
- smallworld/emulators/angr/exploration/terminate.py +22 -0
- smallworld/emulators/angr/factory.py +55 -0
- smallworld/emulators/angr/machdefs/__init__.py +35 -0
- smallworld/emulators/angr/machdefs/aarch64.py +292 -0
- smallworld/emulators/angr/machdefs/amd64.py +192 -0
- smallworld/emulators/angr/machdefs/arm.py +387 -0
- smallworld/emulators/angr/machdefs/i386.py +221 -0
- smallworld/emulators/angr/machdefs/machdef.py +138 -0
- smallworld/emulators/angr/machdefs/mips.py +184 -0
- smallworld/emulators/angr/machdefs/mips64.py +189 -0
- smallworld/emulators/angr/machdefs/ppc.py +101 -0
- smallworld/emulators/angr/machdefs/riscv.py +261 -0
- smallworld/emulators/angr/machdefs/xtensa.py +255 -0
- smallworld/emulators/angr/memory/__init__.py +7 -0
- smallworld/emulators/angr/memory/default.py +10 -0
- smallworld/emulators/angr/memory/fixups.py +43 -0
- smallworld/emulators/angr/memory/memtrack.py +105 -0
- smallworld/emulators/angr/scratch.py +43 -0
- smallworld/emulators/angr/simos.py +53 -0
- smallworld/emulators/angr/utils.py +70 -0
- smallworld/emulators/emulator.py +1013 -0
- smallworld/emulators/hookable.py +252 -0
- smallworld/emulators/panda/__init__.py +5 -0
- smallworld/emulators/panda/machdefs/__init__.py +28 -0
- smallworld/emulators/panda/machdefs/aarch64.py +93 -0
- smallworld/emulators/panda/machdefs/amd64.py +71 -0
- smallworld/emulators/panda/machdefs/arm.py +89 -0
- smallworld/emulators/panda/machdefs/i386.py +36 -0
- smallworld/emulators/panda/machdefs/machdef.py +86 -0
- smallworld/emulators/panda/machdefs/mips.py +94 -0
- smallworld/emulators/panda/machdefs/mips64.py +91 -0
- smallworld/emulators/panda/machdefs/ppc.py +79 -0
- smallworld/emulators/panda/panda.py +575 -0
- smallworld/emulators/unicorn/__init__.py +13 -0
- smallworld/emulators/unicorn/machdefs/__init__.py +28 -0
- smallworld/emulators/unicorn/machdefs/aarch64.py +310 -0
- smallworld/emulators/unicorn/machdefs/amd64.py +326 -0
- smallworld/emulators/unicorn/machdefs/arm.py +321 -0
- smallworld/emulators/unicorn/machdefs/i386.py +137 -0
- smallworld/emulators/unicorn/machdefs/machdef.py +117 -0
- smallworld/emulators/unicorn/machdefs/mips.py +202 -0
- smallworld/emulators/unicorn/unicorn.py +684 -0
- smallworld/exceptions/__init__.py +5 -0
- smallworld/exceptions/exceptions.py +85 -0
- smallworld/exceptions/unstable/__init__.py +1 -0
- smallworld/exceptions/unstable/exceptions.py +25 -0
- smallworld/extern/__init__.py +4 -0
- smallworld/extern/ctypes.py +94 -0
- smallworld/extern/unstable/__init__.py +1 -0
- smallworld/extern/unstable/ghidra.py +129 -0
- smallworld/helpers.py +107 -0
- smallworld/hinting/__init__.py +8 -0
- smallworld/hinting/hinting.py +214 -0
- smallworld/hinting/hints.py +427 -0
- smallworld/hinting/unstable/__init__.py +2 -0
- smallworld/hinting/utils.py +19 -0
- smallworld/instructions/__init__.py +18 -0
- smallworld/instructions/aarch64.py +20 -0
- smallworld/instructions/arm.py +18 -0
- smallworld/instructions/bsid.py +67 -0
- smallworld/instructions/instructions.py +258 -0
- smallworld/instructions/mips.py +21 -0
- smallworld/instructions/x86.py +100 -0
- smallworld/logging.py +90 -0
- smallworld/platforms.py +95 -0
- smallworld/py.typed +0 -0
- smallworld/state/__init__.py +6 -0
- smallworld/state/cpus/__init__.py +32 -0
- smallworld/state/cpus/aarch64.py +563 -0
- smallworld/state/cpus/amd64.py +676 -0
- smallworld/state/cpus/arm.py +630 -0
- smallworld/state/cpus/cpu.py +71 -0
- smallworld/state/cpus/i386.py +239 -0
- smallworld/state/cpus/mips.py +374 -0
- smallworld/state/cpus/mips64.py +372 -0
- smallworld/state/cpus/powerpc.py +229 -0
- smallworld/state/cpus/riscv.py +357 -0
- smallworld/state/cpus/xtensa.py +80 -0
- smallworld/state/memory/__init__.py +7 -0
- smallworld/state/memory/code.py +70 -0
- smallworld/state/memory/elf/__init__.py +3 -0
- smallworld/state/memory/elf/elf.py +564 -0
- smallworld/state/memory/elf/rela/__init__.py +32 -0
- smallworld/state/memory/elf/rela/aarch64.py +27 -0
- smallworld/state/memory/elf/rela/amd64.py +32 -0
- smallworld/state/memory/elf/rela/arm.py +51 -0
- smallworld/state/memory/elf/rela/i386.py +32 -0
- smallworld/state/memory/elf/rela/mips.py +45 -0
- smallworld/state/memory/elf/rela/ppc.py +45 -0
- smallworld/state/memory/elf/rela/rela.py +63 -0
- smallworld/state/memory/elf/rela/riscv64.py +27 -0
- smallworld/state/memory/elf/rela/xtensa.py +15 -0
- smallworld/state/memory/elf/structs.py +55 -0
- smallworld/state/memory/heap.py +85 -0
- smallworld/state/memory/memory.py +181 -0
- smallworld/state/memory/stack/__init__.py +31 -0
- smallworld/state/memory/stack/aarch64.py +22 -0
- smallworld/state/memory/stack/amd64.py +42 -0
- smallworld/state/memory/stack/arm.py +66 -0
- smallworld/state/memory/stack/i386.py +22 -0
- smallworld/state/memory/stack/mips.py +34 -0
- smallworld/state/memory/stack/mips64.py +34 -0
- smallworld/state/memory/stack/ppc.py +34 -0
- smallworld/state/memory/stack/riscv.py +22 -0
- smallworld/state/memory/stack/stack.py +127 -0
- smallworld/state/memory/stack/xtensa.py +34 -0
- smallworld/state/models/__init__.py +6 -0
- smallworld/state/models/mmio.py +186 -0
- smallworld/state/models/model.py +163 -0
- smallworld/state/models/posix.py +455 -0
- smallworld/state/models/x86/__init__.py +2 -0
- smallworld/state/models/x86/microsoftcdecl.py +35 -0
- smallworld/state/models/x86/systemv.py +240 -0
- smallworld/state/state.py +962 -0
- smallworld/state/unstable/__init__.py +0 -0
- smallworld/state/unstable/elf.py +393 -0
- smallworld/state/x86_registers.py +30 -0
- smallworld/utils.py +935 -0
- smallworld_re-1.0.0.dist-info/LICENSE.txt +21 -0
- smallworld_re-1.0.0.dist-info/METADATA +189 -0
- smallworld_re-1.0.0.dist-info/RECORD +166 -0
- smallworld_re-1.0.0.dist-info/WHEEL +5 -0
- smallworld_re-1.0.0.dist-info/entry_points.txt +2 -0
- smallworld_re-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,630 @@
|
|
1
|
+
import typing
|
2
|
+
|
3
|
+
from ... import platforms
|
4
|
+
from .. import state
|
5
|
+
from . import cpu
|
6
|
+
|
7
|
+
# ARM32 has a number of variants with very odd overlaps. Rather than risk
|
8
|
+
# copy-paste errors as I figure out who gets which control registers, I've
|
9
|
+
# implemented each subsystem variant in its own mixin.
|
10
|
+
|
11
|
+
|
12
|
+
class ARM(cpu.CPU):
|
13
|
+
"""Base class for ARM 32-bit CPU models.
|
14
|
+
|
15
|
+
All ARM CPUs share the same basic registers, but there are at least two
|
16
|
+
dimensions of difference for the available modes.
|
17
|
+
"""
|
18
|
+
|
19
|
+
# Special registers:
|
20
|
+
# r13: stack pointer
|
21
|
+
# r14: link register
|
22
|
+
# r15: Program counter
|
23
|
+
_GENERAL_PURPOSE_REGS = [f"r{i}" for i in range(0, 13)]
|
24
|
+
|
25
|
+
def get_general_purpose_registers(self) -> typing.List[str]:
|
26
|
+
return self._GENERAL_PURPOSE_REGS
|
27
|
+
|
28
|
+
def __init__(self):
|
29
|
+
super().__init__()
|
30
|
+
# *** General-purpose registers ***
|
31
|
+
self.r0 = state.Register("r0", size=4)
|
32
|
+
self.add(self.r0)
|
33
|
+
self.r1 = state.Register("r1", size=4)
|
34
|
+
self.add(self.r1)
|
35
|
+
self.r2 = state.Register("r2", size=4)
|
36
|
+
self.add(self.r2)
|
37
|
+
self.r3 = state.Register("r3", size=4)
|
38
|
+
self.add(self.r3)
|
39
|
+
self.r4 = state.Register("r4", size=4)
|
40
|
+
self.add(self.r4)
|
41
|
+
self.r5 = state.Register("r5", size=4)
|
42
|
+
self.add(self.r5)
|
43
|
+
self.r6 = state.Register("r6", size=4)
|
44
|
+
self.add(self.r6)
|
45
|
+
self.r7 = state.Register("r7", size=4)
|
46
|
+
self.add(self.r7)
|
47
|
+
self.r8 = state.Register("r8", size=4)
|
48
|
+
self.add(self.r8)
|
49
|
+
# r9 doubles as the Static base pointer
|
50
|
+
self.r9 = state.Register("r9", size=4)
|
51
|
+
self.add(self.r9)
|
52
|
+
self.sb = state.RegisterAlias("sb", self.r9, size=4, offset=0)
|
53
|
+
self.add(self.sb)
|
54
|
+
# r10 doubles as the Stack Limit pointer
|
55
|
+
self.r10 = state.Register("r10", size=4)
|
56
|
+
self.add(self.r10)
|
57
|
+
self.sl = state.RegisterAlias("sl", self.r10, size=4, offset=0)
|
58
|
+
self.add(self.sl)
|
59
|
+
# r11 doubles as the Frame Pointer, if desired.
|
60
|
+
self.r11 = state.Register("r11", size=4)
|
61
|
+
self.add(self.r11)
|
62
|
+
self.fp = state.RegisterAlias("fp", self.r11, size=4, offset=0)
|
63
|
+
self.add(self.fp)
|
64
|
+
# r12 doubles as the Intra-call scratch register
|
65
|
+
self.r12 = state.Register("r12", size=4)
|
66
|
+
self.add(self.r12)
|
67
|
+
self.ip = state.RegisterAlias("ip", self.r12, size=4, offset=0)
|
68
|
+
self.add(self.ip)
|
69
|
+
self.sp = state.Register("sp", size=4)
|
70
|
+
self.add(self.sp)
|
71
|
+
self.lr = state.Register("lr", size=4)
|
72
|
+
self.add(self.lr)
|
73
|
+
self.pc = state.Register("pc", size=4)
|
74
|
+
self.add(self.pc)
|
75
|
+
|
76
|
+
|
77
|
+
class ARMCPUMixinM:
|
78
|
+
"""Abstract class for M-series CPUs.
|
79
|
+
|
80
|
+
The main difference between M and R/A
|
81
|
+
is the available system status registers.
|
82
|
+
"""
|
83
|
+
|
84
|
+
def __init__(self):
|
85
|
+
super().__init__()
|
86
|
+
# *** Special Registers ***
|
87
|
+
# Program Status Register
|
88
|
+
# NOTE: PSR can be accessed through several masked aliases.
|
89
|
+
# These are read-only, so I'm not including them.
|
90
|
+
# - apsr: Just the condition flags
|
91
|
+
# - ipsr: Just exception information
|
92
|
+
# - epsr: Just execution state info
|
93
|
+
# - iapsr: apsr | ipsr
|
94
|
+
# - eapsr: apsr | epsr
|
95
|
+
# - iepsr: ipsr | epsr
|
96
|
+
# - xpsr: apsr | ipsr | epsr
|
97
|
+
#
|
98
|
+
# NOTE: Unicorn doesn't have a model for PSR, only its aliases
|
99
|
+
self.psr = state.Register("psr", size=4)
|
100
|
+
self.add(self.psr)
|
101
|
+
# Exception Mask Register
|
102
|
+
self.primask = state.Register("primask", size=4)
|
103
|
+
self.add(self.primask)
|
104
|
+
# Base Priority Mask Register
|
105
|
+
self.basepri = state.Register("basepri", size=4)
|
106
|
+
self.add(self.basepri)
|
107
|
+
# Fault Mask Register
|
108
|
+
self.faultmask = state.Register("faultmask", size=4)
|
109
|
+
self.add(self.faultmask)
|
110
|
+
# Control register; includes a lot of flags.
|
111
|
+
self.control = state.Register("control", size=4)
|
112
|
+
self.add(self.control)
|
113
|
+
|
114
|
+
# *** Stack Pointer Bank ***
|
115
|
+
# sp is actually an alias to one of these two.
|
116
|
+
# Exactly which one depends on a bit in control.
|
117
|
+
# Emulators that care should be careful when loading state.
|
118
|
+
|
119
|
+
# Main Stack Pointer
|
120
|
+
self.msp = state.Register("msp", size=4)
|
121
|
+
self.add(self.msp)
|
122
|
+
# Process Stack Pointer
|
123
|
+
self.psp = state.Register("psp", size=4)
|
124
|
+
self.add(self.psp)
|
125
|
+
|
126
|
+
|
127
|
+
class ARMCPUMixinRA:
|
128
|
+
"""Mixin for R- or A-series CPUs.
|
129
|
+
|
130
|
+
The main difference between M and R/A
|
131
|
+
is the available system status registers.
|
132
|
+
"""
|
133
|
+
|
134
|
+
def __init__(self):
|
135
|
+
super().__init__()
|
136
|
+
# *** Special Registers ***
|
137
|
+
# Current Program Status Register
|
138
|
+
# NOTE: CPSR can be accessed through several masked aliases.
|
139
|
+
# These are read-only, so I'm not including them.
|
140
|
+
# - isetstate: Just includes instruction set control bits
|
141
|
+
# - itstate: Just includes state bits for Thumb IT instruction
|
142
|
+
self.cpsr = state.Register("cpsr", size=4)
|
143
|
+
self.add(self.cpsr)
|
144
|
+
# Saved Program Status Register
|
145
|
+
self.spsr = state.Register("spsr", size=4)
|
146
|
+
self.add(self.spsr)
|
147
|
+
|
148
|
+
# *** Register Banks ***
|
149
|
+
# sp, lr, and spsr are actually aliases to one of these.
|
150
|
+
# Which one they reference depends on execution mode.
|
151
|
+
# Emulators that care should be careful when loading state.
|
152
|
+
# NOTE: Use User-mode copies of registers unless the mode has its own.
|
153
|
+
|
154
|
+
# User-mode Stack Pointer
|
155
|
+
self.sp_usr = state.Register("sp_usr", size=4)
|
156
|
+
self.add(self.sp_usr)
|
157
|
+
# User-mode Link Register
|
158
|
+
self.lr_usr = state.Register("lr_usr", size=4)
|
159
|
+
self.add(self.lr_usr)
|
160
|
+
# User-mode r8
|
161
|
+
self.r8_usr = state.Register("r8_usr", size=4)
|
162
|
+
self.add(self.r8_usr)
|
163
|
+
# User-mode r9
|
164
|
+
self.r9_usr = state.Register("r9_usr", size=4)
|
165
|
+
self.add(self.r9_usr)
|
166
|
+
# User-mode r10
|
167
|
+
self.r10_usr = state.Register("r10_usr", size=4)
|
168
|
+
self.add(self.r10_usr)
|
169
|
+
# User-mode r11
|
170
|
+
self.r11_usr = state.Register("r11_usr", size=4)
|
171
|
+
self.add(self.r11_usr)
|
172
|
+
# User-mode r12
|
173
|
+
self.r12_usr = state.Register("r12_usr", size=4)
|
174
|
+
self.add(self.r12_usr)
|
175
|
+
|
176
|
+
# Hypervisor Stack Pointer
|
177
|
+
self.sp_hyp = state.Register("sp_hyp", size=4)
|
178
|
+
self.add(self.sp_hyp)
|
179
|
+
# Hypervisor Saved PSR
|
180
|
+
self.spsr_hyp = state.Register("spsr_hyp", size=4)
|
181
|
+
self.add(self.spsr_hyp)
|
182
|
+
# Hypervisor Exception Link Register
|
183
|
+
# NOTE: This isn't so much banked, as it only exists in hypervisor mode.
|
184
|
+
self.elr_hyp = state.Register("elr_hyp", size=4)
|
185
|
+
self.add(self.elr_hyp)
|
186
|
+
|
187
|
+
# Supervisor Stack Pointer
|
188
|
+
self.sp_svc = state.Register("sp_svc", size=4)
|
189
|
+
self.add(self.sp_svc)
|
190
|
+
# Supervisor Link Register
|
191
|
+
self.lr_svc = state.Register("lr_svc", size=4)
|
192
|
+
self.add(self.lr_svc)
|
193
|
+
# Supervisor Saved PSR
|
194
|
+
self.spsr_svc = state.Register("spsr_svc", size=4)
|
195
|
+
self.add(self.spsr_svc)
|
196
|
+
|
197
|
+
# Abort-state Stack Pointer
|
198
|
+
self.sp_abt = state.Register("sp_abt", size=4)
|
199
|
+
self.add(self.sp_abt)
|
200
|
+
# Abort-state Link Register
|
201
|
+
self.lr_abt = state.Register("lr_abt", size=4)
|
202
|
+
self.add(self.lr_abt)
|
203
|
+
# Abort-state Saved PSR
|
204
|
+
self.spsr_abt = state.Register("spsr_abt", size=4)
|
205
|
+
self.add(self.spsr_abt)
|
206
|
+
|
207
|
+
# Undefined-mode Stack Pointer
|
208
|
+
self.sp_und = state.Register("sp_und", size=4)
|
209
|
+
self.add(self.sp_und)
|
210
|
+
# Undefined-mode Link Register
|
211
|
+
self.lr_und = state.Register("lr_und", size=4)
|
212
|
+
self.add(self.lr_und)
|
213
|
+
# Undefined-mode Saved PSR
|
214
|
+
self.spsr_und = state.Register("spsr_und", size=4)
|
215
|
+
self.add(self.spsr_und)
|
216
|
+
|
217
|
+
# Monitor-mode Stack Pointer
|
218
|
+
self.sp_mon = state.Register("sp_mon", size=4)
|
219
|
+
self.add(self.sp_mon)
|
220
|
+
# Monitor-mode Link Register
|
221
|
+
self.lr_mon = state.Register("lr_mon", size=4)
|
222
|
+
self.add(self.lr_mon)
|
223
|
+
# Monitor-mode Saved PSR
|
224
|
+
self.spsr_mon = state.Register("spsr_mon", size=4)
|
225
|
+
self.add(self.spsr_mon)
|
226
|
+
|
227
|
+
# IRQ-mode Stack Pointer
|
228
|
+
self.sp_irq = state.Register("sp_irq", size=4)
|
229
|
+
self.add(self.sp_irq)
|
230
|
+
# IRQ-mode Link Register
|
231
|
+
self.lr_irq = state.Register("lr_irq", size=4)
|
232
|
+
self.add(self.lr_irq)
|
233
|
+
# IRQ-mode Saved PSR
|
234
|
+
self.spsr_irq = state.Register("spsr_irq", size=4)
|
235
|
+
self.add(self.spsr_irq)
|
236
|
+
|
237
|
+
# FIQ-mode Stack Pointer
|
238
|
+
self.sp_fiq = state.Register("sp_fiq", size=4)
|
239
|
+
self.add(self.sp_fiq)
|
240
|
+
# FIQ-mode Link Register
|
241
|
+
self.lr_fiq = state.Register("lr_fiq", size=4)
|
242
|
+
self.add(self.lr_fiq)
|
243
|
+
# FIQ-mode Saved PSR
|
244
|
+
self.spsr_fiq = state.Register("spsr_fiq", size=4)
|
245
|
+
self.add(self.spsr_fiq)
|
246
|
+
# FIQ-mode r8
|
247
|
+
self.r8_fiq = state.Register("r8_fiq", size=4)
|
248
|
+
self.add(self.r8_fiq)
|
249
|
+
# FIQ-mode r9
|
250
|
+
self.r9_fiq = state.Register("r9_fiq", size=4)
|
251
|
+
self.add(self.r9_fiq)
|
252
|
+
# FIQ-mode r10
|
253
|
+
self.r10_fiq = state.Register("r10_fiq", size=4)
|
254
|
+
self.add(self.r10_fiq)
|
255
|
+
# FIQ-mode r11
|
256
|
+
self.r11_fiq = state.Register("r11_fiq", size=4)
|
257
|
+
self.add(self.r11_fiq)
|
258
|
+
# FIQ-mode r12
|
259
|
+
self.r12_fiq = state.Register("r12_fiq", size=4)
|
260
|
+
self.add(self.r12_fiq)
|
261
|
+
|
262
|
+
|
263
|
+
class ARMCPUMixinFPEL:
|
264
|
+
"""Mixin for little-endian ARM CPUs with FP extensions
|
265
|
+
|
266
|
+
This is one kind of floating-point extension
|
267
|
+
which offers 64-bit scalar operations
|
268
|
+
"""
|
269
|
+
|
270
|
+
def __init__(self):
|
271
|
+
super().__init__()
|
272
|
+
# *** Floating point control registers ***
|
273
|
+
# Floating-point Status and Control Register
|
274
|
+
self.fpscr = state.Register("fpscr", size=4)
|
275
|
+
self.add(self.fpscr)
|
276
|
+
# Floating-point Exception Control Register
|
277
|
+
self.fpexc = state.Register("fpexc", size=4)
|
278
|
+
self.add(self.fpexc)
|
279
|
+
# Floating-point System ID Register
|
280
|
+
self.fpsid = state.Register("fpsid", size=4)
|
281
|
+
self.add(self.fpsid)
|
282
|
+
# Media and VFP Feature Register 0
|
283
|
+
self.mvfr0 = state.Register("mvfr0", size=4)
|
284
|
+
self.add(self.mvfr0)
|
285
|
+
# Media and VFP Feature Register 1
|
286
|
+
self.mvfr1 = state.Register("mvfr1", size=4)
|
287
|
+
self.add(self.mvfr1)
|
288
|
+
|
289
|
+
# *** Floating point registers ***
|
290
|
+
self.d0 = state.Register("d0", size=8)
|
291
|
+
self.add(self.d0)
|
292
|
+
self.s0 = state.RegisterAlias("s0", self.d0, size=4, offset=0)
|
293
|
+
self.add(self.s0)
|
294
|
+
self.s1 = state.RegisterAlias("s1", self.d0, size=4, offset=4)
|
295
|
+
self.add(self.s1)
|
296
|
+
self.d1 = state.Register("d1", size=8)
|
297
|
+
self.add(self.d1)
|
298
|
+
self.s2 = state.RegisterAlias("s2", self.d1, size=4, offset=0)
|
299
|
+
self.add(self.s2)
|
300
|
+
self.s3 = state.RegisterAlias("s3", self.d1, size=4, offset=4)
|
301
|
+
self.add(self.s3)
|
302
|
+
self.d2 = state.Register("d2", size=8)
|
303
|
+
self.add(self.d2)
|
304
|
+
self.s4 = state.RegisterAlias("s4", self.d2, size=4, offset=0)
|
305
|
+
self.add(self.s4)
|
306
|
+
self.s5 = state.RegisterAlias("s5", self.d2, size=4, offset=4)
|
307
|
+
self.add(self.s5)
|
308
|
+
self.d3 = state.Register("d3", size=8)
|
309
|
+
self.add(self.d3)
|
310
|
+
self.s6 = state.RegisterAlias("s6", self.d3, size=4, offset=0)
|
311
|
+
self.add(self.s6)
|
312
|
+
self.s7 = state.RegisterAlias("s7", self.d3, size=4, offset=4)
|
313
|
+
self.add(self.s7)
|
314
|
+
self.d4 = state.Register("d4", size=8)
|
315
|
+
self.add(self.d4)
|
316
|
+
self.s8 = state.RegisterAlias("s8", self.d4, size=4, offset=0)
|
317
|
+
self.add(self.s8)
|
318
|
+
self.s9 = state.RegisterAlias("s9", self.d4, size=4, offset=4)
|
319
|
+
self.add(self.s9)
|
320
|
+
self.d5 = state.Register("d5", size=8)
|
321
|
+
self.add(self.d5)
|
322
|
+
self.s10 = state.RegisterAlias("s10", self.d5, size=4, offset=0)
|
323
|
+
self.add(self.s10)
|
324
|
+
self.s11 = state.RegisterAlias("s11", self.d5, size=4, offset=4)
|
325
|
+
self.add(self.s11)
|
326
|
+
self.d6 = state.Register("d6", size=8)
|
327
|
+
self.add(self.d6)
|
328
|
+
self.s12 = state.RegisterAlias("s12", self.d6, size=4, offset=0)
|
329
|
+
self.add(self.s12)
|
330
|
+
self.s13 = state.RegisterAlias("s13", self.d6, size=4, offset=4)
|
331
|
+
self.add(self.s13)
|
332
|
+
self.d7 = state.Register("d7", size=8)
|
333
|
+
self.add(self.d7)
|
334
|
+
self.s14 = state.RegisterAlias("s14", self.d7, size=4, offset=0)
|
335
|
+
self.add(self.s14)
|
336
|
+
self.s15 = state.RegisterAlias("s15", self.d7, size=4, offset=4)
|
337
|
+
self.add(self.s15)
|
338
|
+
self.d8 = state.Register("d8", size=8)
|
339
|
+
self.add(self.d8)
|
340
|
+
self.s16 = state.RegisterAlias("s16", self.d8, size=4, offset=0)
|
341
|
+
self.add(self.s16)
|
342
|
+
self.s17 = state.RegisterAlias("s17", self.d8, size=4, offset=4)
|
343
|
+
self.add(self.s17)
|
344
|
+
self.d9 = state.Register("d9", size=8)
|
345
|
+
self.add(self.d9)
|
346
|
+
self.s18 = state.RegisterAlias("s18", self.d9, size=4, offset=0)
|
347
|
+
self.add(self.s18)
|
348
|
+
self.s19 = state.RegisterAlias("s19", self.d9, size=4, offset=4)
|
349
|
+
self.add(self.s19)
|
350
|
+
self.d10 = state.Register("d10", size=8)
|
351
|
+
self.add(self.d10)
|
352
|
+
self.s20 = state.RegisterAlias("s20", self.d10, size=4, offset=0)
|
353
|
+
self.add(self.s20)
|
354
|
+
self.s21 = state.RegisterAlias("s21", self.d10, size=4, offset=4)
|
355
|
+
self.add(self.s21)
|
356
|
+
self.d11 = state.Register("d11", size=8)
|
357
|
+
self.add(self.d11)
|
358
|
+
self.s22 = state.RegisterAlias("s22", self.d11, size=4, offset=0)
|
359
|
+
self.add(self.s22)
|
360
|
+
self.s23 = state.RegisterAlias("s23", self.d11, size=4, offset=4)
|
361
|
+
self.add(self.s23)
|
362
|
+
self.d12 = state.Register("d12", size=8)
|
363
|
+
self.add(self.d12)
|
364
|
+
self.s24 = state.RegisterAlias("s24", self.d12, size=4, offset=0)
|
365
|
+
self.add(self.s24)
|
366
|
+
self.s25 = state.RegisterAlias("s25", self.d12, size=4, offset=4)
|
367
|
+
self.add(self.s25)
|
368
|
+
self.d13 = state.Register("d13", size=8)
|
369
|
+
self.add(self.d13)
|
370
|
+
self.s26 = state.RegisterAlias("s26", self.d13, size=4, offset=0)
|
371
|
+
self.add(self.s26)
|
372
|
+
self.s27 = state.RegisterAlias("s27", self.d13, size=4, offset=4)
|
373
|
+
self.add(self.s27)
|
374
|
+
self.d14 = state.Register("d14", size=8)
|
375
|
+
self.add(self.d14)
|
376
|
+
self.s28 = state.RegisterAlias("s28", self.d14, size=4, offset=0)
|
377
|
+
self.add(self.s28)
|
378
|
+
self.s29 = state.RegisterAlias("s29", self.d14, size=4, offset=4)
|
379
|
+
self.add(self.s29)
|
380
|
+
self.d15 = state.Register("d15", size=8)
|
381
|
+
self.add(self.d15)
|
382
|
+
self.s30 = state.RegisterAlias("s30", self.d15, size=4, offset=0)
|
383
|
+
self.add(self.s30)
|
384
|
+
self.s31 = state.RegisterAlias("s31", self.d15, size=4, offset=4)
|
385
|
+
self.add(self.s31)
|
386
|
+
|
387
|
+
|
388
|
+
class ARMCPUMixinVFPEL:
|
389
|
+
"""Mixin for little-endian ARM CPUs with VFP/NEON mixins
|
390
|
+
|
391
|
+
This is one kind of floating-point extension
|
392
|
+
which supports up to 128-bit scalar and SIMD vector operations.
|
393
|
+
|
394
|
+
VFP and NEON are always optional extensions;
|
395
|
+
The two can exist independently, and VFP can support either
|
396
|
+
16 or 32 double registers.
|
397
|
+
This is the maximal set of registers, assuming both are supported.
|
398
|
+
"""
|
399
|
+
|
400
|
+
def __init__(self):
|
401
|
+
super().__init__()
|
402
|
+
# *** Floating-point Control Registers ***
|
403
|
+
# Floating-point Status and Control Register
|
404
|
+
self.fpscr = state.Register("fpscr", size=4)
|
405
|
+
self.add(self.fpscr)
|
406
|
+
# Floating-point Exception Control Register
|
407
|
+
self.fpexc = state.Register("fpexc", size=4)
|
408
|
+
self.add(self.fpexc)
|
409
|
+
# Floating-point System ID Register
|
410
|
+
self.fpsid = state.Register("fpsid", size=4)
|
411
|
+
self.add(self.fpsid)
|
412
|
+
# Media and VFP Feature Register 0
|
413
|
+
self.mvfr0 = state.Register("mvfr0", size=4)
|
414
|
+
self.add(self.mvfr0)
|
415
|
+
# Media and VFP Feature Register 1
|
416
|
+
self.mvfr1 = state.Register("mvfr1", size=4)
|
417
|
+
self.add(self.mvfr1)
|
418
|
+
# *** Floating-point Registers ****
|
419
|
+
self.q0 = state.Register("q0", size=16)
|
420
|
+
self.add(self.q0)
|
421
|
+
self.d0 = state.RegisterAlias("d0", self.q0, size=8, offset=0)
|
422
|
+
self.add(self.d0)
|
423
|
+
self.s0 = state.RegisterAlias("s0", self.q0, size=4, offset=0)
|
424
|
+
self.add(self.s0)
|
425
|
+
self.s1 = state.RegisterAlias("s1", self.q0, size=4, offset=4)
|
426
|
+
self.add(self.s1)
|
427
|
+
self.d1 = state.RegisterAlias("d1", self.q0, size=8, offset=8)
|
428
|
+
self.add(self.d1)
|
429
|
+
self.s2 = state.RegisterAlias("s2", self.q0, size=4, offset=8)
|
430
|
+
self.add(self.s2)
|
431
|
+
self.s3 = state.RegisterAlias("s3", self.q0, size=4, offset=12)
|
432
|
+
self.add(self.s3)
|
433
|
+
self.q1 = state.Register("q1", size=16)
|
434
|
+
self.add(self.q1)
|
435
|
+
self.d2 = state.RegisterAlias("d2", self.q1, size=8, offset=0)
|
436
|
+
self.add(self.d2)
|
437
|
+
self.s4 = state.RegisterAlias("s4", self.q1, size=4, offset=0)
|
438
|
+
self.add(self.s4)
|
439
|
+
self.s5 = state.RegisterAlias("s5", self.q1, size=4, offset=4)
|
440
|
+
self.add(self.s5)
|
441
|
+
self.d3 = state.RegisterAlias("d3", self.q1, size=8, offset=8)
|
442
|
+
self.add(self.d3)
|
443
|
+
self.s6 = state.RegisterAlias("s6", self.q1, size=4, offset=8)
|
444
|
+
self.add(self.s6)
|
445
|
+
self.s7 = state.RegisterAlias("s7", self.q1, size=4, offset=12)
|
446
|
+
self.add(self.s7)
|
447
|
+
self.q2 = state.Register("q2", size=16)
|
448
|
+
self.add(self.q2)
|
449
|
+
self.d4 = state.RegisterAlias("d4", self.q2, size=8, offset=0)
|
450
|
+
self.add(self.d4)
|
451
|
+
self.s8 = state.RegisterAlias("s8", self.q2, size=4, offset=0)
|
452
|
+
self.add(self.s8)
|
453
|
+
self.s9 = state.RegisterAlias("s9", self.q2, size=4, offset=4)
|
454
|
+
self.add(self.s9)
|
455
|
+
self.d5 = state.RegisterAlias("d5", self.q2, size=8, offset=8)
|
456
|
+
self.add(self.d5)
|
457
|
+
self.s10 = state.RegisterAlias("s10", self.q2, size=4, offset=8)
|
458
|
+
self.add(self.s10)
|
459
|
+
self.s11 = state.RegisterAlias("s11", self.q2, size=4, offset=12)
|
460
|
+
self.add(self.s11)
|
461
|
+
self.q3 = state.Register("q3", size=16)
|
462
|
+
self.add(self.q3)
|
463
|
+
self.d6 = state.RegisterAlias("d6", self.q3, size=8, offset=0)
|
464
|
+
self.add(self.d6)
|
465
|
+
self.s12 = state.RegisterAlias("s12", self.q3, size=4, offset=0)
|
466
|
+
self.add(self.s12)
|
467
|
+
self.s13 = state.RegisterAlias("s13", self.q3, size=4, offset=4)
|
468
|
+
self.add(self.s13)
|
469
|
+
self.d7 = state.RegisterAlias("d7", self.q3, size=8, offset=8)
|
470
|
+
self.add(self.d7)
|
471
|
+
self.s14 = state.RegisterAlias("s14", self.q3, size=4, offset=8)
|
472
|
+
self.add(self.s14)
|
473
|
+
self.s15 = state.RegisterAlias("s15", self.q3, size=4, offset=12)
|
474
|
+
self.add(self.s15)
|
475
|
+
self.q4 = state.Register("q4", size=16)
|
476
|
+
self.add(self.q4)
|
477
|
+
self.d8 = state.RegisterAlias("d8", self.q4, size=8, offset=0)
|
478
|
+
self.add(self.d8)
|
479
|
+
self.s16 = state.RegisterAlias("s16", self.q4, size=4, offset=0)
|
480
|
+
self.add(self.s16)
|
481
|
+
self.s17 = state.RegisterAlias("s17", self.q4, size=4, offset=4)
|
482
|
+
self.add(self.s17)
|
483
|
+
self.d9 = state.RegisterAlias("d9", self.q4, size=8, offset=8)
|
484
|
+
self.add(self.d9)
|
485
|
+
self.s18 = state.RegisterAlias("s18", self.q4, size=4, offset=8)
|
486
|
+
self.add(self.s18)
|
487
|
+
self.s19 = state.RegisterAlias("s19", self.q4, size=4, offset=12)
|
488
|
+
self.add(self.s19)
|
489
|
+
self.q5 = state.Register("q5", size=16)
|
490
|
+
self.add(self.q5)
|
491
|
+
self.d10 = state.RegisterAlias("d10", self.q5, size=8, offset=0)
|
492
|
+
self.add(self.d10)
|
493
|
+
self.s20 = state.RegisterAlias("s20", self.q5, size=4, offset=0)
|
494
|
+
self.add(self.s20)
|
495
|
+
self.s21 = state.RegisterAlias("s21", self.q5, size=4, offset=4)
|
496
|
+
self.add(self.s21)
|
497
|
+
self.d11 = state.RegisterAlias("d11", self.q5, size=8, offset=8)
|
498
|
+
self.add(self.d11)
|
499
|
+
self.s22 = state.RegisterAlias("s22", self.q5, size=4, offset=8)
|
500
|
+
self.add(self.s22)
|
501
|
+
self.s23 = state.RegisterAlias("s23", self.q5, size=4, offset=12)
|
502
|
+
self.add(self.s23)
|
503
|
+
self.q6 = state.Register("q6", size=16)
|
504
|
+
self.add(self.q6)
|
505
|
+
self.d12 = state.RegisterAlias("d12", self.q6, size=8, offset=0)
|
506
|
+
self.add(self.d12)
|
507
|
+
self.s24 = state.RegisterAlias("s24", self.q6, size=4, offset=0)
|
508
|
+
self.add(self.s24)
|
509
|
+
self.s25 = state.RegisterAlias("s25", self.q6, size=4, offset=4)
|
510
|
+
self.add(self.s25)
|
511
|
+
self.d13 = state.RegisterAlias("d13", self.q6, size=8, offset=8)
|
512
|
+
self.add(self.d13)
|
513
|
+
self.s26 = state.RegisterAlias("s26", self.q6, size=4, offset=8)
|
514
|
+
self.add(self.s26)
|
515
|
+
self.s27 = state.RegisterAlias("s27", self.q6, size=4, offset=12)
|
516
|
+
self.add(self.s27)
|
517
|
+
self.q7 = state.Register("q7", size=16)
|
518
|
+
self.add(self.q7)
|
519
|
+
self.d14 = state.RegisterAlias("d14", self.q7, size=8, offset=0)
|
520
|
+
self.add(self.d14)
|
521
|
+
self.s28 = state.RegisterAlias("s28", self.q7, size=4, offset=0)
|
522
|
+
self.add(self.s28)
|
523
|
+
self.s29 = state.RegisterAlias("s29", self.q7, size=4, offset=4)
|
524
|
+
self.add(self.s29)
|
525
|
+
self.d15 = state.RegisterAlias("d15", self.q7, size=8, offset=8)
|
526
|
+
self.add(self.d15)
|
527
|
+
self.s30 = state.RegisterAlias("s30", self.q7, size=4, offset=8)
|
528
|
+
self.add(self.s30)
|
529
|
+
self.s31 = state.RegisterAlias("s31", self.q7, size=4, offset=12)
|
530
|
+
self.add(self.s31)
|
531
|
+
# NOTE: This isn't a typo; there are only 32 single-precision sX registers
|
532
|
+
# This does mean that only half the VFP register space can be used
|
533
|
+
# for single-precision arithmetic.
|
534
|
+
self.q8 = state.Register("q8", size=16)
|
535
|
+
self.add(self.q8)
|
536
|
+
self.d16 = state.RegisterAlias("d16", self.q8, size=8, offset=0)
|
537
|
+
self.add(self.d16)
|
538
|
+
self.d17 = state.RegisterAlias("d17", self.q8, size=8, offset=8)
|
539
|
+
self.add(self.d17)
|
540
|
+
self.q9 = state.Register("q9", size=16)
|
541
|
+
self.add(self.q9)
|
542
|
+
self.d18 = state.RegisterAlias("d18", self.q9, size=8, offset=0)
|
543
|
+
self.add(self.d18)
|
544
|
+
self.d19 = state.RegisterAlias("d19", self.q9, size=8, offset=8)
|
545
|
+
self.add(self.d19)
|
546
|
+
self.q10 = state.Register("q10", size=16)
|
547
|
+
self.add(self.q10)
|
548
|
+
self.d20 = state.RegisterAlias("d20", self.q10, size=8, offset=0)
|
549
|
+
self.add(self.d20)
|
550
|
+
self.d21 = state.RegisterAlias("d21", self.q10, size=8, offset=8)
|
551
|
+
self.add(self.d21)
|
552
|
+
self.q11 = state.Register("q11", size=16)
|
553
|
+
self.add(self.q11)
|
554
|
+
self.d22 = state.RegisterAlias("d22", self.q11, size=8, offset=0)
|
555
|
+
self.add(self.d22)
|
556
|
+
self.d23 = state.RegisterAlias("d23", self.q11, size=8, offset=8)
|
557
|
+
self.add(self.d23)
|
558
|
+
self.q12 = state.Register("q12", size=16)
|
559
|
+
self.add(self.q12)
|
560
|
+
self.d24 = state.RegisterAlias("d24", self.q12, size=8, offset=0)
|
561
|
+
self.add(self.d24)
|
562
|
+
self.d25 = state.RegisterAlias("d25", self.q12, size=8, offset=8)
|
563
|
+
self.add(self.d25)
|
564
|
+
self.q13 = state.Register("q13", size=16)
|
565
|
+
self.add(self.q13)
|
566
|
+
self.d26 = state.RegisterAlias("d26", self.q13, size=8, offset=0)
|
567
|
+
self.add(self.d26)
|
568
|
+
self.d27 = state.RegisterAlias("d27", self.q13, size=8, offset=8)
|
569
|
+
self.add(self.d27)
|
570
|
+
self.q14 = state.Register("q14", size=16)
|
571
|
+
self.add(self.q14)
|
572
|
+
self.d28 = state.RegisterAlias("d28", self.q14, size=8, offset=0)
|
573
|
+
self.add(self.d28)
|
574
|
+
self.d29 = state.RegisterAlias("d29", self.q14, size=8, offset=8)
|
575
|
+
self.add(self.d29)
|
576
|
+
self.q15 = state.Register("q15", size=16)
|
577
|
+
self.add(self.q15)
|
578
|
+
self.d30 = state.RegisterAlias("d30", self.q15, size=8, offset=0)
|
579
|
+
self.add(self.d30)
|
580
|
+
self.d31 = state.RegisterAlias("d31", self.q15, size=8, offset=8)
|
581
|
+
self.add(self.d31)
|
582
|
+
|
583
|
+
|
584
|
+
class ARMv5T(ARMCPUMixinM, ARM):
|
585
|
+
"""CPU Model for ARMv5t little-endian."""
|
586
|
+
|
587
|
+
platform = platforms.Platform(
|
588
|
+
platforms.Architecture.ARM_V5T, platforms.Byteorder.LITTLE
|
589
|
+
)
|
590
|
+
|
591
|
+
|
592
|
+
class ARMv6M(ARMCPUMixinFPEL, ARMCPUMixinM, ARM):
|
593
|
+
"""CPU Model for ARMv6-M little-endian."""
|
594
|
+
|
595
|
+
platform = platforms.Platform(
|
596
|
+
platforms.Architecture.ARM_V6M, platforms.Byteorder.LITTLE
|
597
|
+
)
|
598
|
+
|
599
|
+
|
600
|
+
class ARMv6MThumb(ARMv6M):
|
601
|
+
"""CPU Model for ARMv6-M little-endian in thumb mode."""
|
602
|
+
|
603
|
+
platform = platforms.Platform(
|
604
|
+
platforms.Architecture.ARM_V6M_THUMB, platforms.Byteorder.LITTLE
|
605
|
+
)
|
606
|
+
|
607
|
+
|
608
|
+
class ARMv7M(ARMCPUMixinFPEL, ARMCPUMixinM, ARM):
|
609
|
+
"""CPU Model for ARMv7-M little-endian."""
|
610
|
+
|
611
|
+
platform = platforms.Platform(
|
612
|
+
platforms.Architecture.ARM_V7M, platforms.Byteorder.LITTLE
|
613
|
+
)
|
614
|
+
|
615
|
+
|
616
|
+
class ARMv7R(ARMCPUMixinVFPEL, ARMCPUMixinRA, ARM):
|
617
|
+
"""CPU Model for ARMv7-R little-endian."""
|
618
|
+
|
619
|
+
# TODO: v7r and v7a have different MMUs, which I don't implement yet.
|
620
|
+
platform = platforms.Platform(
|
621
|
+
platforms.Architecture.ARM_V7R, platforms.Byteorder.LITTLE
|
622
|
+
)
|
623
|
+
|
624
|
+
|
625
|
+
class ARMv7A(ARMCPUMixinVFPEL, ARMCPUMixinRA, ARM):
|
626
|
+
"""CPU Model for ARMv7-A little-endian."""
|
627
|
+
|
628
|
+
platform = platforms.Platform(
|
629
|
+
platforms.Architecture.ARM_V7A, platforms.Byteorder.LITTLE
|
630
|
+
)
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import abc
|
2
|
+
import typing
|
3
|
+
|
4
|
+
from ... import platforms, utils
|
5
|
+
from .. import state
|
6
|
+
|
7
|
+
|
8
|
+
class CPU(state.StatefulSet):
|
9
|
+
"""A CPU state object."""
|
10
|
+
|
11
|
+
def __deepcopy__(self, memo):
|
12
|
+
new_cpu = (type(self))()
|
13
|
+
for x in self.__dict__:
|
14
|
+
a = self.__getattribute__(x)
|
15
|
+
if type(a) is state.Register:
|
16
|
+
new_cpu.__getattribute__(x).set(self.__getattribute__(x).get())
|
17
|
+
new_cpu.__getattribute__(x).set_label(
|
18
|
+
self.__getattribute__(x).get_label()
|
19
|
+
)
|
20
|
+
new_cpu.__getattribute__(x).set_type(
|
21
|
+
self.__getattribute__(x).get_type()
|
22
|
+
)
|
23
|
+
return new_cpu
|
24
|
+
|
25
|
+
@property
|
26
|
+
@abc.abstractmethod
|
27
|
+
def platform(self) -> platforms.Platform:
|
28
|
+
pass
|
29
|
+
|
30
|
+
@classmethod
|
31
|
+
def get_platform(cls) -> platforms.Platform:
|
32
|
+
"""Get the platform object for this CPU.
|
33
|
+
|
34
|
+
Returns:
|
35
|
+
The platform object for this CPU.
|
36
|
+
"""
|
37
|
+
if not isinstance(cls.platform, platforms.Platform):
|
38
|
+
raise TypeError(f"{cls.__name__}.platform is not a Platform object")
|
39
|
+
return cls.platform
|
40
|
+
|
41
|
+
@classmethod
|
42
|
+
def for_platform(cls, platform: platforms.Platform):
|
43
|
+
"""Get a CPU object for a given platform specifier.
|
44
|
+
|
45
|
+
Arguments:
|
46
|
+
platform: The platform specificer for the desired CPU object.
|
47
|
+
|
48
|
+
Returns:
|
49
|
+
An instance of the desired CPU.
|
50
|
+
"""
|
51
|
+
|
52
|
+
try:
|
53
|
+
return utils.find_subclass(cls, lambda x: x.get_platform() == platform)
|
54
|
+
except ValueError:
|
55
|
+
raise ValueError(f"no model for {platform}")
|
56
|
+
|
57
|
+
@abc.abstractmethod
|
58
|
+
def get_general_purpose_registers(self) -> typing.List[str]:
|
59
|
+
"""Get a list of general purpose register names.
|
60
|
+
|
61
|
+
Returns:
|
62
|
+
A list of the general purpose register names for this CPU.
|
63
|
+
"""
|
64
|
+
|
65
|
+
pass
|
66
|
+
|
67
|
+
def __repr__(self) -> str:
|
68
|
+
return f"{self.__class__.__name__}({self.platform})"
|
69
|
+
|
70
|
+
|
71
|
+
__all__ = ["CPU"]
|