-
Notifications
You must be signed in to change notification settings - Fork 0
/
RARVirtualMachine.h
189 lines (153 loc) · 5.9 KB
/
RARVirtualMachine.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
* RARVirtualMachine.h
*
* Copyright (c) 2017-present, MacPaw Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#ifndef __RARVIRTUALMACHINE_H__
#define __RARVIRTUALMACHINE_H__
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <limits.h>
#define RARProgramMemorySize 0x40000
#define RARProgramMemoryMask (RARProgramMemorySize-1)
#define RARProgramWorkSize 0x3c000
#define RARProgramGlobalSize 0x2000
#define RARProgramSystemGlobalAddress RARProgramWorkSize
#define RARProgramSystemGlobalSize 64
#define RARProgramUserGlobalAddress (RARProgramSystemGlobalAddress+RARProgramSystemGlobalSize)
#define RARProgramUserGlobalSize (RARProgramGlobalSize-RARProgramSystemGlobalSize)
typedef struct RARVirtualMachine
{
uint32_t registers[8];
uint32_t flags;
// TODO: align?
uint8_t memory[RARProgramMemorySize+3]; // Let memory accesses at the end overflow.
// Possibly not 100% correct but unlikely to be a problem.
} RARVirtualMachine;
typedef uint32_t (*RARGetterFunction)(RARVirtualMachine *self,uint32_t value);
typedef void (*RARSetterFunction)(RARVirtualMachine *self,uint32_t value,uint32_t data);
typedef struct RAROpcode
{
void *instructionlabel;
RARGetterFunction operand1getter;
RARSetterFunction operand1setter;
uint32_t value1;
RARGetterFunction operand2getter;
RARSetterFunction operand2setter;
uint32_t value2;
uint8_t instruction;
uint8_t bytemode;
uint8_t addressingmode1;
uint8_t addressingmode2;
#if UINTPTR_MAX==UINT64_MAX
uint8_t padding[12]; // 64-bit machine, pad to 64 bytes
#endif
} RAROpcode;
// Setup
void InitializeRARVirtualMachine(RARVirtualMachine *self);
// Program building
void SetRAROpcodeInstruction(RAROpcode *opcode,unsigned int instruction,bool bytemode);
void SetRAROpcodeOperand1(RAROpcode *opcode,unsigned int addressingmode,uint32_t value);
void SetRAROpcodeOperand2(RAROpcode *opcode,unsigned int addressingmode,uint32_t value);
bool IsProgramTerminated(RAROpcode *opcodes,int numopcodes);
bool PrepareRAROpcodes(RAROpcode *opcodes,int numopcodes);
// Execution
bool ExecuteRARCode(RARVirtualMachine *self,RAROpcode *opcodes,int numopcodes);
// Instruction properties
int NumberOfRARInstructionOperands(unsigned int instruction);
bool RARInstructionHasByteMode(unsigned int instruction);
bool RARInstructionIsUnconditionalJump(unsigned int instruction);
bool RARInstructionIsRelativeJump(unsigned int instruction);
bool RARInstructionWritesFirstOperand(unsigned int instruction);
bool RARInstructionWritesSecondOperand(unsigned int instruction);
// Disassembling
char *DescribeRAROpcode(RAROpcode *opcode);
char *DescribeRARInstruction(RAROpcode *opcode);
char *DescribeRAROperand1(RAROpcode *opcode);
char *DescribeRAROperand2(RAROpcode *opcode);
static inline void SetRARVirtualMachineRegisters(RARVirtualMachine *self,uint32_t registers[8])
{
memcpy(self->registers,registers,sizeof(self->registers));
}
static inline uint32_t _RARRead32(const uint8_t *b) { return ((uint32_t)b[3]<<24)|((uint32_t)b[2]<<16)|((uint32_t)b[1]<<8)|(uint32_t)b[0]; }
static inline void _RARWrite32(uint8_t *b,uint32_t n) { b[3]=(n>>24)&0xff; b[2]=(n>>16)&0xff; b[1]=(n>>8)&0xff; b[0]=n&0xff; }
static inline uint32_t RARVirtualMachineRead32(RARVirtualMachine *self,uint32_t address)
{
return _RARRead32(&self->memory[address&RARProgramMemoryMask]);
}
static inline void RARVirtualMachineWrite32(RARVirtualMachine *self,uint32_t address,uint32_t val)
{
_RARWrite32(&self->memory[address&RARProgramMemoryMask],val);
}
static inline uint32_t RARVirtualMachineRead8(RARVirtualMachine *self,uint32_t address)
{
return self->memory[address&RARProgramMemoryMask];
}
static inline void RARVirtualMachineWrite8(RARVirtualMachine *self,uint32_t address,uint32_t val)
{
self->memory[address&RARProgramMemoryMask]=val;
}
#define RARMovInstruction 0
#define RARCmpInstruction 1
#define RARAddInstruction 2
#define RARSubInstruction 3
#define RARJzInstruction 4
#define RARJnzInstruction 5
#define RARIncInstruction 6
#define RARDecInstruction 7
#define RARJmpInstruction 8
#define RARXorInstruction 9
#define RARAndInstruction 10
#define RAROrInstruction 11
#define RARTestInstruction 12
#define RARJsInstruction 13
#define RARJnsInstruction 14
#define RARJbInstruction 15
#define RARJbeInstruction 16
#define RARJaInstruction 17
#define RARJaeInstruction 18
#define RARPushInstruction 19
#define RARPopInstruction 20
#define RARCallInstruction 21
#define RARRetInstruction 22
#define RARNotInstruction 23
#define RARShlInstruction 24
#define RARShrInstruction 25
#define RARSarInstruction 26
#define RARNegInstruction 27
#define RARPushaInstruction 28
#define RARPopaInstruction 29
#define RARPushfInstruction 30
#define RARPopfInstruction 31
#define RARMovzxInstruction 32
#define RARMovsxInstruction 33
#define RARXchgInstruction 34
#define RARMulInstruction 35
#define RARDivInstruction 36
#define RARAdcInstruction 37
#define RARSbbInstruction 38
#define RARPrintInstruction 39
#define RARNumberOfInstructions 40
#define RARRegisterAddressingMode(n) (0+(n))
#define RARRegisterIndirectAddressingMode(n) (8+(n))
#define RARIndexedAbsoluteAddressingMode(n) (16+(n))
#define RARAbsoluteAddressingMode 24
#define RARImmediateAddressingMode 25
#define RARNumberOfAddressingModes 26
#endif