OpenCores
URL https://opencores.org/ocsvn/forwardcom/forwardcom/trunk

Subversion Repositories forwardcom

[/] [forwardcom/] [bintools/] [emulator.h] - Blame information for rev 142

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 33 Agner
/****************************  emulator.h   **********************************
2
* Author:        Agner Fog
3
* date created:  2018-02-18
4
* Last modified: 2021-04-02
5
* Version:       1.11
6
* Project:       Binary tools for ForwardCom instruction set
7
* Module:        emulator.h
8
* Description:
9
* Header file for emulator
10
*
11
* Copyright 2018-2021 GNU General Public License http://www.gnu.org/licenses
12
*****************************************************************************/
13
 
14
// structure for memory map
15
struct SMemoryMap {
16
    uint64_t startAddress;                       // virtual address boundary (must be divisible by 8)
17
    uint64_t access_addend;                      // (access_addend & 7) is access permission: SHF_READ, SHF_WRITE, SHF_EXEC
18
                                                 // (access_addend & ~7) is added to the virtual address to get physical address
19
};
20
 
21
// union for an operand value of any type
22
union SNum {
23
    uint64_t q;                                  // 64 bit unsigned integer
24
    int64_t  qs;                                 // 64 bit signed integer
25
    uint32_t i;                                  // 32 bit unsigned integer
26
    int32_t  is;                                 // 32 bit signed integer
27
    uint16_t s;                                  // 16 bit unsigned integer
28
    int16_t  ss;                                 // 16 bit signed integer
29
    uint8_t  b;                                  // 8 bit  unsigned integer
30
    int8_t   bs;                                 // 8 bit  signed integer
31
    double d;                                    // double precision float
32
    float f;                                     // single precision float
33
};
34
 
35
// Indexes into perfCounters array
36
const int perf_cpu_clock_cycles = 1;
37
const int perf_instructions = 2;
38
const int perf_2size_instructions = 3;
39
const int perf_3size_instructions = 4;
40
const int perf_gp_instructions = 5;
41
const int perf_gp_instructions_mask0 = 6;
42
const int perf_vector_instructions = 7;
43
const int perf_control_transfer_instructions = 8;
44
const int perf_direct_jumps = 9;
45
const int perf_indirect_jumps = 10;
46
const int perf_cond_jumps = 11;
47
const int perf_unknown_instruction = 12;
48
const int perf_wrong_operands = 13;
49
const int perf_array_overflow = 14;
50
const int perf_read_violation = 15;
51
const int perf_write_violation = 16;
52
const int perf_misaligned = 17;
53
const int perf_address_of_first_error = 18;
54
const int perf_type_of_first_error = 19;
55
const int number_of_perf_counters = 20;          // number of performance counter registers
56
 
57
// Indexes into capabilities registers array
58
const int disable_errors_capability_register = 2;// register for disabling errors
59
const int number_of_capability_registers = 16;   // number of capability registers
60
class CEmulator;                                 // preliminary declaration
61
 
62
// Class for a thread or CPU core in the emulator
63
class CThread {
64
public:
65
    CThread();                                   // constructor
66
    ~CThread();                                  // destructor
67
    void run();                                  // start running
68
    void setRegisters(CEmulator * emulator);     // initialize registers etc.
69
    uint64_t ip;                                 // instruction pointer
70
    uint64_t ip0;                                // address base for code and read-only data
71
    uint64_t datap;                              // base pointer for writeable data
72
    uint64_t threadp;                            // base pointer for thread-local data
73
    uint64_t ninstructions;                      // number of instructions executed
74
    uint32_t numContr;                           // numeric control register
75
    uint32_t lastMask;                           // shows last status of subnormal support
76
    uint32_t options;                            // option bits in instruction
77
    uint32_t exception;                          // exception or jump caused by current instruction
78
    STemplate const * pInstr;                    // current instruction code
79
    SFormat  const * fInstr;                     // format of current instruction
80
    SNum     parm[6];                            // parm[0] = value of first operand if 3 operands
81
                                                 // parm[1] = value of first operand if 2 operands or second operand if 3 operands
82
                                                 // parm[2] = value of last operand
83
                                                 // parm[3] = value of mask register or NUMCONTR
84
                                                 // parm[4] = value of immediate operand without shift or conversion
85
                                                 // parm[5] = high part of double size return value
86
    uint8_t  operands[6];                        // instruction operands. 0x00-0x1F = register. 0x20 = immediate, 0x40 = memory
87
                                                 // operands[0] is destination register
88
                                                 // operands[1] is mask register
89
                                                 // operands[2] is fallback register
90
                                                 // two-operand instructions use operands[4-5]
91
                                                 // three-operand instructions use operands[3-5]
92
    uint8_t  op;                                 // operation code
93
    uint8_t  operandType;                        // operand type for current instruction
94
    uint8_t  nOperands;                          // number of source operands for current instruction
95
    uint8_t  vect;                               // instruction uses vector registers
96
    uint8_t  running;                            // thread is running. 0 = stop, 1 = save RD, 2 = don't save RD
97
    bool     readonly;                           // expect memory address to be in read-only section
98
    bool     ignoreMask;                         // call execution function even if mask is zero
99
    bool     doubleStep;                         // execution function will process two vector elements at a time
100
    bool     noVectorLength;                     // RS is not a vector register, or vector length is determined by execution function
101
    bool     dontRead;                           // don't read source operand before execution
102
    bool     unchangedRd;                        // store instruction: RD is not destination
103
    bool     terminate;                          // stop execution
104
    bool     memory_error;                       // memory address error
105
    CMemoryBuffer vectors;                       // vector register i is at offset i*MaxVectorLength
106
    uint64_t registers[32];                      // value of register r0 - r31
107
    uint32_t vectorLength[32];                   // length of vector registers v0 - v31
108
    uint32_t vectorLengthM;                      // vector length of memory operand
109
    uint32_t vectorLengthR;                      // vector length of result
110
    uint32_t vectorOffset;                       // offset to current element within vector
111
    uint32_t MaxVectorLength;                    // maximum vector length
112
    uint32_t returnType;                         // debug return output. bit 0-3: operand type (8 = half precision). bit 4: register. bit 5: memory. //(bit6: one extra element save_cp)
113
                                                 // bit 8: vector. bit 12: jump. bit 13: jump taken
114
    int8_t * memory;                             // program memory
115
    int8_t * tempBuffer;                         // temporary buffer for vector operand
116
    uint64_t memAddress;                         // address of memory operand
117
    int64_t  addrOperand;                        // relative address of memory operand or jump target
118
    uint64_t readVectorElement(uint32_t v, uint32_t vectorOffset); // read vector element
119
    void writeVectorElement(uint32_t v, uint64_t value, uint32_t vectorOffset); // write vector element
120
    uint64_t getMemoryAddress();                 // get address of a memory operand
121
    uint64_t readMemoryOperand(uint64_t address);// read a memory operand
122
    void writeMemoryOperand(uint64_t val, uint64_t address);  // write a memory operand
123
    void interrupt(uint32_t n);                  // interrupt or trap
124
    uint64_t checkSysMemAccess(uint64_t address, uint64_t size, uint8_t rd, uint8_t rs, uint8_t mode);
125
    int fprintfEmulated(FILE * stream, const char * format, uint64_t * argumentList); // emulate fprintf with ForwardCom argument list
126
    // check if system function has access to a particular address
127
    void systemCall(uint32_t mod, uint32_t funcid, uint8_t rd, uint8_t rs); // entry for system calls
128
    uint64_t makeNan(uint32_t code, uint32_t operandType);// make a NAN with exception code and address in payload
129
    CDynamicArray<uint64_t> callStack;           // stack of return addresses
130
    uint32_t callDept;                           // maximum number of entries observed in callStack
131
    uint64_t entry_point;                        // program entry point
132
    uint64_t perfCounters[number_of_perf_counters];// performance counters
133
    uint64_t capabilyReg[number_of_capability_registers];// capability registers
134
protected:
135
    uint32_t mapIndex1;                          // last memory map index for code
136
    uint32_t mapIndex2;                          // last memory map index for read-only data
137
    uint32_t mapIndex3;                          // last memory map index for writeable data
138
    CEmulator * emulator;                        // pointer to owner
139
    CDynamicArray<SMemoryMap> memoryMap;         // memory map
140
    CTextFileBuffer listOut;                     // output debug listing
141
    uint32_t listFileName;                       // file name for listOut (index into cmd.fileNameBuffer)
142
    uint32_t listLines;                          // line counter
143
    void fetch();                                // fetch next instruction
144
    void decode();                               // decode current instruction
145
    void execute();                              // execute current instruction
146
    void listStart();                            // start writing debug list
147
    void listInstruction(uint64_t address);      // write current instruction to debug list
148
public:
149
    void listResult(uint64_t result);            // write result of current instruction to debug list
150
    void performanceCounters();                  // update performance counters
151
    uint64_t readRegister(uint8_t reg) {         // read register value
152
        if (vect) {                              // this function is inlined for performance reasons
153
            uint64_t val = vectors.get<uint64_t>(reg*MaxVectorLength);
154
            if (vectorLength[reg] < 8) {
155
                // vector is less than 8 bytes. zero-extend to 8 bytes
156
                val &= ((uint64_t)1 << vectorLength[reg]) - 1;
157
            }
158
            return val;
159
        }
160
        else {
161
            return registers[reg];
162
        }
163
    }
164
};
165
 
166
// Class for the whole emulator
167
class CEmulator : public CELF {
168
public:
169
    CEmulator();                                 // constructor
170
    ~CEmulator();                                // destructor
171
    void go();                                   // start
172
protected:
173
    void load();                                 // load executable file into memory
174
    void relocate();                             // relocate any absolute addresses and system function id's
175
    void disassemble();                          // make disassembly listing for debug output
176
    uint32_t MaxVectorLength;                    // maximum vector length
177
    int8_t * memory;                             // program memory
178
    uint64_t memsize;                            // total allocated memory size
179
    uint32_t maxNumThreads;                      // maximum number of threads
180
    uint64_t ip0;                                // address base for code and read-only data
181
    uint64_t datap0;                             // address base for writeable data
182
    uint64_t threadp0;                           // address base for thread data of main thread
183
    uint64_t stackp;                             // pointer to stack
184
    uint64_t stackSize;                          // data stack size for main thread
185
    uint64_t callStackSize;                      // call stack size for main thread
186
    uint64_t heapSize;                           // heap size for main thread
187
    uint32_t environmentSize;                    // maximum size of environment and command line data
188
    CMetaBuffer<CThread> threads;                // one or more threads
189
    CDynamicArray<SMemoryMap> memoryMap;         // main memory map
190
    CDynamicArray<SLineRef> lineList;            // Cross reference of code addresses to lines in dissassembler output
191
    CTextFileBuffer disassemOut;                 // Output file from disassembler
192
    CDisassembler disassembler;                  // disassembler for producing output list
193
    friend class CThread;
194
};
195
 
196
// Functions for floating point exception and rounding control
197
void setRoundingMode(uint8_t r);
198
void clearExceptionFlags();
199
uint32_t getExceptionFlags();
200
void enableSubnormals(uint32_t e);
201
 
202
// universal function type for execution function
203
// all operands and option bits are accessed via *thread
204
typedef uint64_t (*PFunc)(CThread * thread);
205
 
206
// Tables of execution functions
207
extern PFunc funcTab1[64];                       // multiformat instructions
208
extern PFunc funcTab2[64];                       // jump instructions
209
extern PFunc funcTab3[16];                       // jump instructions with 24 bit offset
210
// single format instructions:
211
extern PFunc funcTab4[64];                       // format 1.0
212
extern PFunc funcTab5[64];                       // format 1.1
213
extern PFunc funcTab6[64];                       // format 1.2
214
extern PFunc funcTab7[64];                       // format 1.3
215
extern PFunc funcTab8[64];                       // format 1.4
216
extern PFunc funcTab9[64];                       // format 1.8
217
extern PFunc funcTab10[64];                      // format 2.5
218
extern PFunc funcTab11[64];                      // format 2.6
219
extern PFunc funcTab12[64];                      // format 2.9
220
extern PFunc funcTab13[64];                      // format 3.1
221
 
222
// Table of execution function tables, indexed by fInstr->exeTable
223
extern PFunc * metaFunctionTable[];
224
// Table of dispatch functions for single format instructions with E template
225
extern PFunc EDispatchTable[];
226
 
227
// Table of number of operands for each instruction
228
extern uint8_t numOperands[15][64];
229
extern uint8_t numOperands2071[64];
230
extern uint8_t numOperands2261[64];
231
extern uint8_t numOperands2271[64];
232
 
233
// Execution functions shared between multiple cpp files
234
uint64_t f_nop(CThread * thread);
235
uint64_t f_add(CThread * thread);
236
uint64_t f_sub(CThread * thread);
237
uint64_t f_mul(CThread * thread);
238
uint64_t f_div(CThread * thread);
239
uint64_t f_mul_add(CThread * thread);
240
uint64_t f_add_h(CThread * thread);
241
uint64_t f_mul_h(CThread * thread);
242
uint64_t insert_(CThread * t);
243
uint64_t extract_(CThread * t);
244
uint64_t bitscan_(CThread * t);
245
uint64_t popcount_(CThread * t);
246
int64_t  mul64_128s(uint64_t * low, int64_t a, int64_t b);
247
uint64_t mul64_128u(uint64_t * low, uint64_t a, uint64_t b);
248
 
249
// constants and functions for detecting NAN and infinity
250
const uint16_t inf_h   = 0x7C00;                 // float16 infinity
251
const uint16_t inf2h   = inf_h*2;                // for detecting infinity when sign bit has been shifted out
252
const uint32_t inf_f   = 0x7F800000;             // float infinity
253
const uint32_t inf2f   = inf_f*2;                // for detecting infinity when sign bit has been shifted out
254
const uint32_t nan_f   = 0x7FC00000;             // float nan
255
const uint32_t sign_f  = 0x80000000;             // float  sign bit
256
const uint32_t nsign_f = 0x7FFFFFFF;             // float not sign bit
257
const uint64_t inf_d   = 0x7FF0000000000000;     // double infinity
258
const uint64_t inf2d   = inf_d*2;                // for detecting infinity when sign bit has been shifted out
259
const uint64_t nan_d   = 0x7FF8000000000000;     // double nan
260
const uint64_t nsign_d = 0x7FFFFFFFFFFFFFFF;     // double not sign bit
261
const uint64_t sign_d  = 0x8000000000000000;     // double sign bit
262
 
263
// functions applied to the bit representations of floating point numbers to detect NAN and infinity:
264
static inline bool isnan_h(uint16_t x) {return uint16_t(x << 1) > inf2h;}
265
static inline bool isnan_f(uint32_t x) {return (x << 1) > inf2f;}
266
static inline bool isnan_d(uint64_t x) {return (x << 1) > inf2d;}
267
static inline bool isinf_h(uint16_t x) {return uint16_t(x << 1) == inf2h;}
268
static inline bool isinf_f(uint32_t x) {return (x << 1) == inf2f;}
269
static inline bool isinf_d(uint64_t x) {return (x << 1) == inf2d;}
270
static inline bool isnan_or_inf_h(uint16_t x) {return uint16_t(x << 1) >= inf2h;}
271
static inline bool isnan_or_inf_f(uint32_t x) {return (x << 1) >= inf2f;}
272
static inline bool isnan_or_inf_d(uint64_t x) {return (x << 1) >= inf2d;}
273
static inline bool is_zero_or_subnormal_h(uint16_t x) {return (x & 0x7C00) == 0;}
274
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.