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

Subversion Repositories altor32

[/] [altor32/] [trunk/] [or1k-sim/] [or32.cpp] - Blame information for rev 40

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

Line No. Rev Author Line
1 28 ultra_embe
//-----------------------------------------------------------------
2
//                           AltOR32 
3
//                Alternative Lightweight OpenRisc 
4
//                            V2.0
5
//                     Ultra-Embedded.com
6
//                   Copyright 2011 - 2013
7
//
8
//               Email: admin@ultra-embedded.com
9
//
10
//                       License: LGPL
11
//-----------------------------------------------------------------
12
//
13
// Copyright (C) 2011 - 2013 Ultra-Embedded.com
14
//
15
// This source file may be used and distributed without         
16
// restriction provided that this copyright statement is not    
17
// removed from the file and that any derivative work contains  
18
// the original copyright notice and the associated disclaimer. 
19
//
20
// This source file is free software; you can redistribute it   
21
// and/or modify it under the terms of the GNU Lesser General   
22
// Public License as published by the Free Software Foundation; 
23
// either version 2.1 of the License, or (at your option) any   
24
// later version.
25
//
26
// This source is distributed in the hope that it will be       
27
// useful, but WITHOUT ANY WARRANTY; without even the implied   
28
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
29
// PURPOSE.  See the GNU Lesser General Public License for more 
30
// details.
31
//
32
// You should have received a copy of the GNU Lesser General    
33
// Public License along with this source; if not, write to the 
34
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
35
// Boston, MA  02111-1307  USA
36
//-----------------------------------------------------------------
37
#include <stdio.h>
38
#include <string.h>
39
#include <stdlib.h>
40
#include <assert.h>
41
#include "or32.h"
42
 
43
#ifdef INCLUDE_INST_DUMP
44
    #include "or32_inst_dump.h"
45
#endif
46
 
47
//-----------------------------------------------------------------
48
// Defines:
49
//-----------------------------------------------------------------
50
#define DPRINTF(l,a)        do { if (Trace & l) printf a; } while (0)
51
#define TRACE_ENABLED(l)    (Trace & l)
52
 
53
#define MEMTRACE_WRITES     "mem_writes.txt"
54
#define MEMTRACE_READS      "mem_reads.txt"
55
#define MEMTRACE_INST       "mem_inst.txt"
56
#define MEMTRACE_MIN        100
57
 
58
#define ADD_CARRY_OUT(a,b)  ((((unsigned long long)(a) + (unsigned long long)(b)) & ((unsigned long long)1 << 32)) != 0)
59
 
60
#define HTONL(n) (((((unsigned int)(n) & 0xFF)) << 24) | \
61
                ((((unsigned int)(n) & 0xFF00)) << 8) | \
62
                ((((unsigned int)(n) & 0xFF0000)) >> 8) | \
63
                ((((unsigned int)(n) & 0xFF000000)) >> 24))
64
 
65
//-----------------------------------------------------------------
66
// Constructor
67
//-----------------------------------------------------------------
68
OR32::OR32(bool delay_slot)
69
{
70
    MemRegions = 0;
71
 
72
    int m;
73
    for (m=0;m<MAX_MEM_REGIONS;m++)
74
    {
75
        MemInstHits[m] = NULL;
76
        MemReadHits[m] = NULL;
77
        MemWriteHits[m] = NULL;
78
    }
79
 
80
    MemVectorBase = 0;
81
 
82
    Trace = 0;
83
    DelaySlotEnabled = delay_slot;
84
    EnablePutc = true;
85
 
86
    Reset();
87
}
88
//-----------------------------------------------------------------
89
// Constructor
90
//-----------------------------------------------------------------
91
OR32::OR32(unsigned int baseAddr, unsigned int len, bool delay_slot)
92
{
93
    int m;
94
 
95
    MemBase[0] = baseAddr;
96
    MemSize[0] = len;
97
 
98
    Mem[0] = new TMemory[(len + 3)/4];
99
    assert(Mem[0]);
100
    memset(Mem[0], 0, (len + 3)/4);
101
 
102
    MemRegions = 1;
103
 
104
    for (m=0;m<MAX_MEM_REGIONS;m++)
105
    {
106
        MemInstHits[m] = NULL;
107
        MemReadHits[m] = NULL;
108
        MemWriteHits[m] = NULL;
109
    }
110
 
111
    MemVectorBase = baseAddr;
112
 
113
    Trace = 0;
114
    DelaySlotEnabled = delay_slot;
115
    EnablePutc = true;
116
 
117
    Reset();
118
}
119
//-----------------------------------------------------------------
120
// Deconstructor
121
//-----------------------------------------------------------------
122
OR32::~OR32()
123
{
124
    int m;
125
 
126
    for (m=0;m<MemRegions;m++)
127
    {
128
        if (Mem[m])
129
            delete Mem[m];
130
        Mem[m] = NULL;
131
    }
132
}
133
//-----------------------------------------------------------------
134
// CreateMemory:
135
//-----------------------------------------------------------------
136
bool OR32::CreateMemory(unsigned int baseAddr, unsigned int len)
137
{
138
    if (MemRegions < MAX_MEM_REGIONS)
139
    {
140
        MemBase[MemRegions] = baseAddr;
141
        MemSize[MemRegions] = len;
142
 
143
        Mem[MemRegions] = new TMemory[(len + 3)/4];
144
        if (!Mem[MemRegions])
145
            return false;
146
 
147
        memset(Mem[MemRegions], 0, (len + 3)/4);
148
 
149
        MemRegions++;
150
 
151
        return true;
152
    }
153
 
154
    return false;
155
}
156
//-----------------------------------------------------------------
157
// EnableMemoryTrace:
158
//-----------------------------------------------------------------
159
void OR32::EnableMemoryTrace(void)
160
{
161
    int m;
162
 
163
    for (m=0;m<MemRegions;m++)
164
    {
165
        MemInstHits[m] = new TRegister[MemSize[m]/4];
166
        MemReadHits[m] = new TRegister[MemSize[m]/4];
167
        MemWriteHits[m] = new TRegister[MemSize[m]/4];
168
        assert(MemInstHits[m]);
169
        assert(MemReadHits[m]);
170
        assert(MemWriteHits[m]);
171
 
172
        memset(MemInstHits[m], 0, MemSize[m]);
173
        memset(MemReadHits[m], 0, MemSize[m]);
174
        memset(MemWriteHits[m], 0, MemSize[m]);
175
    }
176
}
177
//-----------------------------------------------------------------
178
// Reset: Reset CPU state
179
//-----------------------------------------------------------------
180
void OR32::Reset(TRegister start_addr /*= VECTOR_RESET*/)
181
{
182
    int i;
183
 
184
    r_pc = start_addr;
185
    r_pc_next = start_addr;
186
    r_pc_last = start_addr;
187
    r_sr = 0;
188
    r_epc = 0;
189
    r_esr = 0;
190
 
191
    for (i=0;i<REGISTERS;i++)
192
        r_gpr[i] = 0;
193
 
194
    r_reg_ra = 0;
195
    r_reg_rb = 0;
196
    r_reg_result = 0;
197
    r_rd_wb = 0;
198
    r_ra = 0;
199
    r_rb = 0;
200
 
201
    mem_addr = 0;
202
    mem_offset = 0;
203
    mem_wr = 0;
204
    mem_rd = 0;
205
    mem_ifetch = 0;
206
 
207
    Fault = 0;
208
    Break = 0;
209
    BreakValue = 0;
210
    Trace = 0;
211
    Cycle = 2;
212
 
213
    MemVectorBase = start_addr - VECTOR_RESET;
214
 
215
    ResetStats();
216
    PeripheralReset();
217
}
218
//-----------------------------------------------------------------
219
// ResetStats: Reset runtime stats
220
//-----------------------------------------------------------------
221
void OR32::ResetStats(void)
222
{
223
    int m;
224
 
225
    // Clear stats
226
    StatsMem = 0;
227
    StatsMarkers = 0;
228
    StatsMemWrites = 0;
229
    StatsInstructions = 0;
230
    StatsNop = 0;
231
    StatsBranches = 0;
232
    StatsExceptions = 0;
233
    StatsMulu = 0;
234
    StatsMul = 0;
235
 
236
    for (m=0;m<MemRegions;m++)
237
    {
238
        if (MemReadHits[m])
239
            memset(MemReadHits[m], 0, MemSize[m]);
240
        if (MemWriteHits[m])
241
            memset(MemWriteHits[m], 0, MemSize[m]);
242
        if (MemInstHits[m])
243
            memset(MemInstHits[m], 0, MemSize[m]);
244
    }
245
}
246
//-----------------------------------------------------------------
247
// Load: Load program code into startAddr offset
248
//-----------------------------------------------------------------
249
bool OR32::Load(unsigned int startAddr, unsigned char *data, int len)
250
{
251
    int i;
252
    int j;
253
 
254
    for (j=0;j<MemRegions;j++)
255
    {
256
        // Program fits in memory?
257
        if ((startAddr >= MemBase[j]) && (startAddr + len) <= (MemBase[j] + MemSize[j]))
258
        {
259
            // Make relative to start of memory
260
            startAddr -= MemBase[j];
261
 
262
            // Convert to word address
263
            startAddr /= 4;
264
 
265
            for (i=0;i<len / 4; i++)
266
            {
267
                Mem[j][startAddr+i] = *data++;
268
                Mem[j][startAddr+i] <<= 8;
269
                Mem[j][startAddr+i]|= *data++;
270
                Mem[j][startAddr+i] <<= 8;
271
                Mem[j][startAddr+i]|= *data++;
272
                Mem[j][startAddr+i] <<= 8;
273
                Mem[j][startAddr+i]|= *data++;
274
 
275
                Mem[j][startAddr+i] = HTONL(Mem[j][startAddr+i]);
276
            }
277
 
278
            return true;
279
        }
280
    }
281
    return false;
282
}
283
//-----------------------------------------------------------------
284
// WriteMem: Write a block of memory
285
//-----------------------------------------------------------------
286
bool OR32::WriteMem(TAddress addr, unsigned char *data, int len)
287
{
288
    int i;
289
    int j;
290
 
291
    for (j=0;j<MemRegions;j++)
292
    {
293
        if (addr >= MemBase[j] && addr < (MemBase[j] + MemSize[j]))
294
        {
295
            unsigned char *ptr = (unsigned char *)Mem[j];
296
            ptr += (addr - MemBase[j]);
297
 
298
            for (i=0;i<len; i++)
299
                ptr[i] = data[i];
300
 
301
            return true;
302
        }
303
    }
304
 
305
    return false;
306
}
307
//-----------------------------------------------------------------
308
// ReadMem: Read a block of memory
309
//-----------------------------------------------------------------
310
bool OR32::ReadMem(TAddress addr, unsigned char *data, int len)
311
{
312
    int i;
313
    int j;
314
 
315
    for (j=0;j<MemRegions;j++)
316
    {
317
        if (addr >= MemBase[j] && addr < (MemBase[j] + MemSize[j]))
318
        {
319
            unsigned char *ptr = (unsigned char *)Mem[j];
320
            ptr += (addr - MemBase[j]);
321
 
322
            for (i=0;i<len; i++)
323
                data[i] = ptr[i];
324
 
325
            return true;
326
        }
327
    }
328
 
329
    return false;
330
}
331
//-----------------------------------------------------------------
332
// GetOpcode: Get instruction from address
333
//-----------------------------------------------------------------
334
TRegister OR32::GetOpcode(TRegister address)
335
{
336
    int m;
337
    for (m=0;m<MemRegions;m++)
338
    {
339
        if (address >= MemBase[m] && address < (MemBase[m] + MemSize[m]))
340
        {
341
            TAddress wordAddress = (address - MemBase[m]) / 4;
342
            TRegister mem_word = Mem[m][wordAddress];
343
            return HTONL(mem_word);
344
        }
345
    }
346
 
347
    return 0;
348
}
349
//-----------------------------------------------------------------
350
// Decode: Instruction decode stage
351
//-----------------------------------------------------------------
352
void OR32::Decode(void)
353
{
354
    // Instruction opcode read complete
355
    mem_wr = 0;
356
    mem_rd = 0;
357
    mem_ifetch = 0;
358
 
359
    // Fetch instruction from 'memory bus'
360
    r_opcode = mem_data_in;
361
    mem_data_in = 0;
362
 
363
    // Decode opcode in-order to perform register reads
364
    r_ra = (r_opcode >> OR32_REG_A_SHIFT) & OR32_REG_A_MASK;
365
    r_rb = (r_opcode >> OR32_REG_B_SHIFT) & OR32_REG_B_MASK;
366
    r_rd = (r_opcode >> OR32_REG_D_SHIFT) & OR32_REG_D_MASK;
367
}
368
//-----------------------------------------------------------------
369
// Execute: Instruction execution stage
370
//-----------------------------------------------------------------
371
void OR32::Execute(void)
372
{
373
    TRegister v_ra = 0;
374
    TRegister v_rb = 0;
375
    TRegister v_rd = 0;
376
    TRegister v_inst = 0;
377
    TRegister v_op = 0;
378
    TRegister v_target = 0;
379
    TRegister v_pc = 0;
380
    TRegister v_pc_next = 0;
381
    TRegister v_imm = 0;
382
    TRegister v_imm_uint32 = 0;
383
    TRegister v_imm_int32 = 0;
384
    TRegister v_offset = 0;
385
    TRegister v_reg_ra = 0;
386
    TRegister v_reg_rb = 0;
387
    TRegister v_reg_result = 0;
388
    TRegister v_store_imm = 0;
389
    int v_branch = 0;
390
    int v_jmp = 0;
391
    int v_exception = 0;
392
    TRegister v_vector = 0;
393
    int v_write_rd = 0;
394
 
395
    TRegister v_alu_op = 0;
396
    TRegister v_shift_op = 0;
397
    TRegister v_sfxx_op = 0;
398
 
399
    // Notify observers of instruction execution
400
    MonInstructionExecute(r_pc, r_opcode);
401
 
402
    StatsInstructions++;
403
 
404
    DPRINTF(LOG_INST, ("%08x: Execute 0x%08x\n", r_pc, r_opcode));
405
    DPRINTF(LOG_INST, (" rA[%2d] = 0x%08x\n", r_ra, r_reg_ra));
406
    DPRINTF(LOG_INST, (" rB[%2d] = 0x%08x\n", r_rb, r_reg_rb));
407
 
408
    // Decode opcode fields
409
    v_inst      = (r_opcode >> OR32_OPCODE_SHIFT) & OR32_OPCODE_MASK;
410
    v_rd        = (r_opcode >> OR32_REG_D_SHIFT) & OR32_REG_D_MASK;
411
    v_ra        = (r_opcode >> OR32_REG_A_SHIFT) & OR32_REG_A_MASK;
412
    v_rb        = (r_opcode >> OR32_REG_B_SHIFT) & OR32_REG_B_MASK;
413
    v_imm       = (r_opcode >> OR32_IMM16_SHIFT) & OR32_IMM16_MASK;
414
    v_target    = (r_opcode >> OR32_ADDR_SHIFT) & OR32_ADDR_MASK;
415
    v_sfxx_op   = (r_opcode >> OR32_SFXXX_OP_SHIFT) & OR32_SFXXX_OP_MASK;
416
    v_alu_op    = (r_opcode >> OR32_ALU_OP_L_SHIFT) & OR32_ALU_OP_L_MASK;
417
    v_alu_op   |= (r_opcode >> OR32_ALU_OP_H_SHIFT) & OR32_ALU_OP_H_MASK;
418
    v_shift_op  = (r_opcode >> OR32_SHIFT_OP_SHIFT) & OR32_SHIFT_OP_MASK;
419
    v_store_imm = (r_opcode >> OR32_STORE_IMM_L_SHIFT) & OR32_STORE_IMM_L_MASK;
420
    v_store_imm|= (r_opcode >> OR32_STORE_IMM_H_SHIFT) & OR32_STORE_IMM_H_MASK;
421
 
422
    // Sign extend store immediate
423
    v_store_imm = (unsigned int)(signed short)v_store_imm;
424
 
425
    // Sign extend target immediate
426
    if (v_target & (1 << OR32_ADDR_SIGN_SHIFT))
427
        v_target |= ~OR32_ADDR_MASK;
428
 
429
    // Signed & unsigned imm -> 32-bits
430
    v_imm_int32 = (unsigned int)(signed short)v_imm;
431
    v_imm_uint32 = v_imm;
432
 
433
    // Load register[ra]
434
    v_reg_ra = r_reg_ra;
435
 
436
    // Load register[rb]
437
    v_reg_rb = r_reg_rb;
438
 
439
    // Zero result
440
    v_reg_result = 0;
441
 
442
    // Default target is r_rd
443
    r_rd_wb = r_rd;
444
 
445
    if (DelaySlotEnabled)
446
    {
447
        // Update PC to next value
448
        v_pc = r_pc_next;
449
 
450
        // Increment next PC value (might be overriden by branch)
451
        v_pc_next = r_pc_next + 4;
452
    }
453
    else
454
    {
455
        v_pc      = r_pc + 4; // Current PC + 4
456
        v_pc_next = r_pc + 8; // Current PC + 8 (used in branches)
457
    }
458
 
459
    // Execute instruction
460
    switch(v_inst)
461
    {
462
        case INST_OR32_ALU:
463
            switch (v_alu_op)
464
            {
465
                case INST_OR32_ADD: // l.add
466
                    v_reg_result = v_reg_ra + v_reg_rb;
467
                    v_write_rd = 1;
468
 
469
                    // Carry out
470
                    r_sr = (r_sr & ~OR32_SR_CY_BIT) | (ADD_CARRY_OUT(v_reg_ra, v_reg_rb) ? OR32_SR_CY_BIT : 0);
471
                break;
472
                case INST_OR32_ADDC: // l.addc
473
                    v_reg_result = v_reg_ra + v_reg_rb + ((r_sr & OR32_SR_CY_BIT) ? 1 : 0);
474
                    v_write_rd = 1;
475
 
476
                    // Carry out
477
                    r_sr = (r_sr & ~OR32_SR_CY_BIT) | (ADD_CARRY_OUT(v_reg_ra, v_reg_rb) ? OR32_SR_CY_BIT : 0);
478
                break;
479
                case INST_OR32_AND: // l.and
480
                    v_reg_result = v_reg_ra & v_reg_rb;
481
                    v_write_rd = 1;
482
                break;
483
                case INST_OR32_OR: // l.or
484
                    v_reg_result = v_reg_ra | v_reg_rb;
485
                    v_write_rd = 1;
486
                break;
487
                case INST_OR32_SLL: // l.sll
488
                    v_reg_result = v_reg_ra << (v_reg_rb & 0x3F);
489
                    v_write_rd = 1;
490
                break;
491
                case INST_OR32_SRA: // l.sra
492
                    v_reg_result = (int)v_reg_ra >> (v_reg_rb & 0x3F);
493
                    v_write_rd = 1;
494
                break;
495
                case INST_OR32_SRL: // l.srl
496
                    v_reg_result = v_reg_ra >> (v_reg_rb & 0x3F);
497
                    v_write_rd = 1;
498
                break;
499
                case INST_OR32_SUB: // l.sub
500
                    v_reg_result = v_reg_ra + ~v_reg_rb + 1;
501
                    v_write_rd = 1;
502
                break;
503
                case INST_OR32_XOR: // l.xor
504
                    v_reg_result = v_reg_ra ^ v_reg_rb;
505
                    v_write_rd = 1;
506
                break;
507
                case INST_OR32_MUL: // l.mul
508
                {
509
                    long long res = ((long long) (int)v_reg_ra) * ((long long)(int)v_reg_rb);
510
                    v_reg_result = (int)(res >> 0);
511
                    v_write_rd = 1;
512
                    StatsMul++;
513
                }
514
                break;
515
                case INST_OR32_MULU: // l.mulu
516
                {
517
                    // This implementation differs from other cores - l.mulu returns upper 
518
                    // 32-bits of multiplication result...
519
                    long long res = ((long long) (int)v_reg_ra) * ((long long)(int)v_reg_rb);
520
                    v_reg_result = (int)(res >> 32);
521
                    v_write_rd = 1;
522
                    StatsMulu++;
523
                }
524
                break;
525
                default:
526
                    fprintf (stderr,"Bad ALU instruction @ PC %x\n", r_pc);
527
                    Fault = 1;
528
                    v_exception = 1;
529
                    v_vector = MemVectorBase + VECTOR_ILLEGAL_INST;
530
                break;
531
            }
532
        break;
533
 
534
        case INST_OR32_ADDI: // l.addi 
535
            v_reg_result = v_reg_ra + v_imm_int32;
536
            v_write_rd = 1;
537
 
538
            // Carry out
539 33 ultra_embe
            r_sr = (r_sr & ~OR32_SR_CY_BIT) | (ADD_CARRY_OUT(v_reg_ra, v_imm_int32) ? OR32_SR_CY_BIT : 0);
540 28 ultra_embe
        break;
541
 
542
        case INST_OR32_ANDI: // l.andi
543
            v_reg_result = v_reg_ra & v_imm_uint32;
544
            v_write_rd = 1;
545
        break;
546
 
547
        case INST_OR32_BF: // l.bf
548
            if (r_sr & OR32_SR_F_BIT)
549
                v_branch = 1;
550
        break;
551
 
552
        case INST_OR32_BNF: // l.bnf
553
            if (!(r_sr & OR32_SR_F_BIT))
554
                v_branch = 1;
555
        break;
556
 
557
        case INST_OR32_J: // l.j
558
            v_branch = 1;
559
        break;
560
 
561
        case INST_OR32_JAL: // l.jal
562
            // Write next instruction address to LR
563
            if (DelaySlotEnabled)
564
                v_reg_result = v_pc_next;
565
            else
566
                v_reg_result = v_pc;
567
            r_rd_wb = REG_9_LR;
568
            v_write_rd = 1;
569
 
570
            v_branch = 1;
571
        break;
572
 
573
        case INST_OR32_JALR: // l.jalr
574
            // Write next instruction address to LR
575
            if (DelaySlotEnabled)
576
                v_reg_result = v_pc_next;
577
            else
578
                v_reg_result = v_pc;
579
            r_rd_wb = REG_9_LR;
580
            v_write_rd = 1;
581
 
582
            if (DelaySlotEnabled)
583
                v_pc_next = v_reg_rb;
584
            else
585
                v_pc = v_reg_rb;
586
            v_jmp = 1;
587
        break;
588
 
589
        case INST_OR32_JR: // l.jr
590
            if (DelaySlotEnabled)
591
                v_pc_next = v_reg_rb;
592
            else
593
                v_pc = v_reg_rb;
594
            v_jmp = 1;
595
        break;
596
 
597
        case INST_OR32_LBS: // l.lbs
598
        case INST_OR32_LHS: // l.lhs
599
        case INST_OR32_LWS: // l.lws
600
        case INST_OR32_LBZ: // l.lbz
601
        case INST_OR32_LHZ: // l.lhz
602
        case INST_OR32_LWZ: // l.lwz
603
            mem_addr = v_reg_ra + (int)v_imm_int32;
604
            mem_offset = mem_addr & 0x3;
605
            mem_wr = 0;
606
            mem_rd = 1;
607
            mem_data_out = 0;
608
            v_write_rd = 1;
609
            StatsMem++;
610
        break;
611
 
612
        case INST_OR32_MFSPR: // l.mfspr
613
            // Move from SPR register
614
            switch ((v_reg_ra | (v_imm_uint32 & OR32_MFSPR_IMM_MASK)))
615
            {
616
                // VR - Version register
617
                case SPR_REG_VR:
618
                    v_reg_result = SPR_VERSION_CURRENT;
619
                    v_write_rd = 1;
620
                break;
621
                // SR - Supervision register
622
                case SPR_REG_SR:
623
                    v_reg_result = r_sr;
624
                    v_write_rd = 1;
625
                break;
626
                // EPCR - EPC Exception saved PC
627
                case SPR_REG_EPCR:
628
                    v_reg_result = r_epc;
629
                    v_write_rd = 1;
630
                break;
631
                // ESR - Exception saved SR
632
                case SPR_REG_ESR:
633
                    v_reg_result = r_esr;
634
                    v_write_rd = 1;
635
                break;
636
                default:
637
                    fprintf (stderr,"Unsupported SPR register (0x%x) access @ PC %x\n", (v_reg_ra | v_imm_uint32), r_pc);
638
                    Fault = 1;
639
                    v_exception = 1;
640
                    v_vector = MemVectorBase + VECTOR_ILLEGAL_INST;
641
                break;
642
            }
643
        break;
644
 
645
        case INST_OR32_MTSPR: // l.mtspr
646
            // Move to SPR register
647
            switch ((v_reg_ra | (v_imm_uint32 & OR32_MTSPR_IMM_MASK)))
648
            {
649
                // SR - Supervision register
650
                case SPR_REG_SR:
651
                    r_sr = v_reg_rb;
652
                break;
653
                // EPCR - EPC Exception saved PC
654
                case SPR_REG_EPCR:
655
                    r_epc = v_reg_rb;
656
                break;
657
                // ESR - Exception saved SR
658
                case SPR_REG_ESR:
659
                    r_esr = v_reg_rb;
660
                break;
661
                default:
662
                    fprintf (stderr,"Unsupported SPR register (0x%x) access @ PC %x\n", (v_reg_ra | v_imm_uint32), r_pc);
663
                    Fault = 1;
664
                    v_exception = 1;
665
                    v_vector = VECTOR_ILLEGAL_INST;
666
                break;
667
            }
668
        break;
669
 
670
        case INST_OR32_MOVHI: // l.movhi
671
            v_reg_result = v_imm_uint32 << 16;
672
            v_write_rd = 1;
673
        break;
674
 
675
        case INST_OR32_NOP: // l.nop
676
            StatsNop++;
677
 
678
            // NOP with simulator instruction?
679
            if (v_imm != NOP_NOP)
680
                MonNop(v_imm);
681
        break;
682
 
683
        case INST_OR32_ORI: // l.ori
684
            v_reg_result = v_reg_ra | v_imm_uint32;
685
            v_write_rd = 1;
686
        break;
687
 
688
        case INST_OR32_RFE: // l.rfe
689
            // Restore PC & SR from EPC & ESR
690
            if (DelaySlotEnabled)
691
                v_pc_next = r_epc;
692
            else
693
                v_pc = r_epc;
694
            r_sr = r_esr;
695
            v_jmp = 1;
696
 
697
            // TODO: Handle branch delay & next instruction flush
698
        break;
699
 
700
        case INST_OR32_SHIFTI:
701
            switch (v_shift_op)
702
            {
703
                case INST_OR32_SLLI: // l.slli
704
                    v_reg_result = v_reg_ra << (r_opcode & 0x3F);
705
                    v_write_rd = 1;
706
                break;
707
                case INST_OR32_SRAI: // l.srai
708
                    v_reg_result = (int)v_reg_ra >> (r_opcode & 0x3F);
709
                    v_write_rd = 1;
710
                break;
711
                case INST_OR32_SRLI: // l.srli
712
                    v_reg_result = v_reg_ra >> (r_opcode & 0x3F);
713
                    v_write_rd = 1;
714
                break;
715
                default:
716
                    fprintf (stderr,"Bad shift instruction @ PC %x\n", r_pc);
717
                    Fault = 1;
718
                    v_exception = 1;
719
                    v_vector = MemVectorBase + VECTOR_ILLEGAL_INST;
720
                break;
721
            }
722
        break;
723
 
724
        case INST_OR32_SB: // l.sb
725
            mem_addr = v_reg_ra + (int)v_store_imm;
726
            mem_offset = mem_addr & 0x3;
727
            mem_rd = 0;
728
            switch (mem_offset)
729
            {
730
                case 0x0:
731
                    mem_data_out = (v_reg_rb & 0xFF) << 24;
732
                    mem_wr = 8;
733
                    break;
734
                case 0x1:
735
                    mem_data_out = (v_reg_rb & 0xFF) << 16;
736
                    mem_wr = 4;
737
                    break;
738
                case 0x2:
739
                    mem_data_out = (v_reg_rb & 0xFF) << 8;
740
                    mem_wr = 2;
741
                    break;
742
                case 0x3:
743
                    mem_data_out = (v_reg_rb & 0xFF) << 0;
744
                    mem_wr = 1;
745
                    break;
746
            }
747
            StatsMem++;
748
            StatsMemWrites++;
749
        break;
750
 
751
        case INST_OR32_SFXX:
752
        case INST_OR32_SFXXI:
753
            switch (v_sfxx_op)
754
            {
755
                case INST_OR32_SFEQ: // l.sfeq
756
                    if (v_reg_ra == v_reg_rb)
757
                        r_sr |= OR32_SR_F_BIT;
758
                    else
759
                        r_sr &=~OR32_SR_F_BIT;
760
                break;
761
                case INST_OR32_SFEQI: // l.sfeqi
762
                    if (v_reg_ra == v_imm_int32)
763
                        r_sr |= OR32_SR_F_BIT;
764
                    else
765
                        r_sr &=~OR32_SR_F_BIT;
766
                break;
767
                case INST_OR32_SFGES: // l.sfges
768
                    if ((int)v_reg_ra >= (int)v_reg_rb)
769
                        r_sr |= OR32_SR_F_BIT;
770
                    else
771
                        r_sr &=~OR32_SR_F_BIT;
772
                break;
773
                case INST_OR32_SFGESI: // l.sfgesi
774
                    if ((int)v_reg_ra >= (int)v_imm_int32)
775
                        r_sr |= OR32_SR_F_BIT;
776
                    else
777
                        r_sr &=~OR32_SR_F_BIT;
778
                break;
779
                case INST_OR32_SFGEU: // l.sfgeu
780
                    if (v_reg_ra >= v_reg_rb)
781
                        r_sr |= OR32_SR_F_BIT;
782
                    else
783
                        r_sr &=~OR32_SR_F_BIT;
784
                break;
785
                case INST_OR32_SFGEUI: // l.sfgeui
786
                    if (v_reg_ra >= v_imm_int32)
787
                        r_sr |= OR32_SR_F_BIT;
788
                    else
789
                        r_sr &=~OR32_SR_F_BIT;
790
                break;
791
                case INST_OR32_SFGTS: // l.sfgts
792
                    if ((int)v_reg_ra > (int)v_reg_rb)
793
                        r_sr |= OR32_SR_F_BIT;
794
                    else
795
                        r_sr &=~OR32_SR_F_BIT;
796
                break;
797
                case INST_OR32_SFGTSI: // l.sfgtsi
798
                    if ((int)v_reg_ra > (int)v_imm_int32)
799
                        r_sr |= OR32_SR_F_BIT;
800
                    else
801
                        r_sr &=~OR32_SR_F_BIT;
802
                break;
803
                case INST_OR32_SFGTU: // l.sfgtu
804
                    if (v_reg_ra > v_reg_rb)
805
                        r_sr |= OR32_SR_F_BIT;
806
                    else
807
                        r_sr &=~OR32_SR_F_BIT;
808
                break;
809
                case INST_OR32_SFGTUI: // l.sfgtui
810
                    if (v_reg_ra > v_imm_int32)
811
                        r_sr |= OR32_SR_F_BIT;
812
                    else
813
                        r_sr &=~OR32_SR_F_BIT;
814
                break;
815
                case INST_OR32_SFLES: // l.sfles
816
                    if ((int)v_reg_ra <= (int)v_reg_rb)
817
                        r_sr |= OR32_SR_F_BIT;
818
                    else
819
                        r_sr &=~OR32_SR_F_BIT;
820
                break;
821
                case INST_OR32_SFLESI: // l.sflesi
822
                    if ((int)v_reg_ra <= (int)v_imm_int32)
823
                        r_sr |= OR32_SR_F_BIT;
824
                    else
825
                        r_sr &=~OR32_SR_F_BIT;
826
                break;
827
                case INST_OR32_SFLEU: // l.sfleu
828
                    if (v_reg_ra <= v_reg_rb)
829
                        r_sr |= OR32_SR_F_BIT;
830
                    else
831
                        r_sr &=~OR32_SR_F_BIT;
832
                break;
833
                case INST_OR32_SFLEUI: // l.sfleui
834
                    if (v_reg_ra <= v_imm_int32)
835
                        r_sr |= OR32_SR_F_BIT;
836
                    else
837
                        r_sr &=~OR32_SR_F_BIT;
838
                break;
839
                case INST_OR32_SFLTS: // l.sflts
840
                    if ((int)v_reg_ra < (int)v_reg_rb)
841
                        r_sr |= OR32_SR_F_BIT;
842
                    else
843
                        r_sr &=~OR32_SR_F_BIT;
844
                break;
845
                case INST_OR32_SFLTSI: // l.sfltsi
846
                    if ((int)v_reg_ra < (int)v_imm_int32)
847
                        r_sr |= OR32_SR_F_BIT;
848
                    else
849
                        r_sr &=~OR32_SR_F_BIT;
850
                break;
851
                case INST_OR32_SFLTU: // l.sfltu
852
                    if (v_reg_ra < v_reg_rb)
853
                        r_sr |= OR32_SR_F_BIT;
854
                    else
855
                        r_sr &=~OR32_SR_F_BIT;
856
                break;
857
                case INST_OR32_SFLTUI: // l.sfltui
858
                    if (v_reg_ra < v_imm_int32)
859
                        r_sr |= OR32_SR_F_BIT;
860
                    else
861
                        r_sr &=~OR32_SR_F_BIT;
862
                break;
863
                case INST_OR32_SFNE: // l.sfne
864
                    if (v_reg_ra != v_reg_rb)
865
                        r_sr |= OR32_SR_F_BIT;
866
                    else
867
                        r_sr &=~OR32_SR_F_BIT;
868
                break;
869
                case INST_OR32_SFNEI: // l.sfnei
870
                    if (v_reg_ra != v_imm_int32)
871
                        r_sr |= OR32_SR_F_BIT;
872
                    else
873
                        r_sr &=~OR32_SR_F_BIT;
874
                break;
875
                default:
876
                    fprintf (stderr,"Bad SFxx instruction @ PC %x\n", r_pc);
877
                    Fault = 1;
878
                    v_exception = 1;
879
                    v_vector = MemVectorBase + VECTOR_ILLEGAL_INST;
880
                break;
881
            }
882
        break;
883
 
884
        case INST_OR32_SH: // l.sh
885
            mem_addr = v_reg_ra + (int)v_store_imm;
886
            mem_offset = mem_addr & 0x3;
887
            mem_rd = 0;
888
            switch (mem_offset)
889
            {
890
                case 0x0:
891
                    mem_data_out = (v_reg_rb & 0xFFFF) << 16;
892
                    mem_wr = 0xC;
893
                    break;
894
                case 0x2:
895
                    mem_data_out = (v_reg_rb & 0xFFFF) << 0;
896
                    mem_wr = 0x3;
897
                    break;
898
                default:
899
                    fprintf (stderr,"Bad mem access @ PC %x (%x)\n", r_pc, mem_offset);
900
                    Fault = 1;
901
                    mem_wr = 0;
902
                    break;
903
            }
904
            StatsMem++;
905
            StatsMemWrites++;
906
        break;
907
 
908
        case INST_OR32_SW: // l.sw
909
            mem_addr = v_reg_ra + (int)v_store_imm;
910
            mem_offset = mem_addr & 0x3;
911
            mem_rd = 0;
912
            mem_wr = 0xF;
913
            mem_data_out = v_reg_rb;
914
            if (mem_offset != 0)
915
            {
916
                fprintf (stderr,"Bad mem access @ PC %x (%x)\n", r_pc, mem_offset);
917
                Fault = 1;
918
                mem_wr = 0;
919
            }
920
            StatsMem++;
921
            StatsMemWrites++;
922
        break;
923
 
924
        case INST_OR32_MISC:
925
            switch (r_opcode >> 24)
926
            {
927
                case INST_OR32_SYS: // l.sys
928
                    v_exception = 1;
929
                    v_vector = MemVectorBase + VECTOR_SYSCALL;
930
                break;
931
 
932
                case INST_OR32_TRAP: // l.trap
933
                    Break = 1;
934
                    BreakValue = v_imm_uint32;
935
                    v_exception = 1;
936
                    v_vector = MemVectorBase + VECTOR_TRAP;
937
                break;
938
            }
939
        break;
940
 
941
        case INST_OR32_XORI: // l.xori
942
            v_reg_result = v_reg_ra ^ v_imm_int32;
943
            v_write_rd = 1;
944
        break;
945
 
946
        default:
947
            fprintf (stderr,"Fault @ PC %x\n", r_pc);
948
            Fault = 1;
949
            v_exception = 1;
950
            v_vector = MemVectorBase + VECTOR_ILLEGAL_INST;
951
        break;
952
   }
953
 
954
    // Notify observer of fault
955
    if (Fault)
956
        MonFault(r_pc, r_opcode);
957
 
958
    // Handle branches (jumps relative to current PC)
959
    if (v_branch == 1)
960
    {
961
        v_offset = v_target << 2;
962
        if (DelaySlotEnabled)
963
            v_pc_next = r_pc + v_offset;
964
        else
965
            v_pc = r_pc + v_offset;
966
        StatsBranches++;
967
    }
968
    // If not branching, handle interrupts / exceptions
969
    else if (v_jmp == 0)
970
    {
971
        // Check for external interrupt
972
        if ((v_exception == 0) && (r_sr & (1 << OR32_SR_IEE)))
973
        {
974
            // External interrupt (and not handling an exception)?
975
            if (PeripheralInterrupt())
976
            {
977
                v_exception = 1;
978
                v_vector = MemVectorBase + VECTOR_EXTINT;
979
            }
980
        }
981
 
982
        // Interrupt / Exception
983
        if (v_exception == 1)
984
        {
985
            // Save PC & SR
986
            r_epc = v_pc;
987
            r_esr = r_sr;
988
 
989
            v_pc = v_vector;
990
            v_pc_next = v_pc + 4;
991
 
992
            // Disable further interrupts
993
            r_sr = 0;
994
 
995
            StatsExceptions++;
996
            StatsBranches++;
997
        }
998
    }
999
    else
1000
        StatsBranches++;
1001
 
1002
    // Update registers with variable values
1003
    if (DelaySlotEnabled)
1004
    {
1005
        r_pc_last = r_pc;
1006
        r_pc = v_pc;
1007
        r_pc_next = v_pc_next;
1008
    }
1009
    else
1010
    {
1011
        r_pc_last = r_pc;
1012
        r_pc = v_pc;
1013
    }
1014
 
1015
    r_reg_result = v_reg_result;
1016
 
1017
    // No writeback required?
1018
    if (v_write_rd == 0)
1019
    {
1020
        // Target register is $0 which is read-only
1021
        r_rd_wb = 0;
1022
    }
1023
}
1024
//-----------------------------------------------------------------
1025
// WriteBack: Register write back stage
1026
//-----------------------------------------------------------------
1027
void OR32::WriteBack(void)
1028
{
1029
    TRegister v_inst;
1030
    TRegister v_reg_result;
1031
 
1032
    mem_wr = 0;
1033
    mem_rd = 0;
1034
    mem_ifetch = 0;
1035
 
1036
    v_inst = (r_opcode >> OR32_OPCODE_SHIFT) & OR32_OPCODE_MASK;
1037
 
1038
    // Writeback read result
1039
    switch(v_inst)
1040
    {
1041
    case INST_OR32_LBS: // l.lbs
1042
        switch (mem_offset)
1043
        {
1044
            case 0x0:
1045
                v_reg_result = (int)((signed char)(mem_data_in >> 24));
1046
                break;
1047
            case 0x1:
1048
                v_reg_result = (int)((signed char)(mem_data_in >> 16));
1049
                break;
1050
            case 0x2:
1051
                v_reg_result = (int)((signed char)(mem_data_in >> 8));
1052
                break;
1053
            case 0x3:
1054
                v_reg_result = (int)((signed char)(mem_data_in >> 0));
1055
                break;
1056
        }
1057
        break;
1058
 
1059
    case INST_OR32_LBZ: // l.lbz
1060
        switch (mem_offset)
1061
        {
1062
            case 0x0:
1063
                v_reg_result = ((unsigned char)(mem_data_in >> 24));
1064
                break;
1065
            case 0x1:
1066
                v_reg_result = ((unsigned char)(mem_data_in >> 16));
1067
                break;
1068
            case 0x2:
1069
                v_reg_result = ((unsigned char)(mem_data_in >> 8));
1070
                break;
1071
            case 0x3:
1072
                v_reg_result = ((unsigned char)(mem_data_in >> 0));
1073
                break;
1074
        }
1075
        break;
1076
 
1077
    case INST_OR32_LHS: // l.lhs
1078
        switch (mem_offset)
1079
        {
1080
            case 0x0:
1081
                v_reg_result = (int)((signed short)(mem_data_in >> 16));
1082
                break;
1083
            case 0x2:
1084
                v_reg_result = (int)((signed short)(mem_data_in >> 0));
1085
                break;
1086
            default:
1087
                fprintf (stderr,"Bad mem access @ PC %x (%x)\n", r_pc, mem_offset);
1088
                Fault = 1;
1089
                break;
1090
        }
1091
        break;
1092
 
1093
    case INST_OR32_LHZ: // l.lhz
1094
        switch (mem_offset)
1095
        {
1096
            case 0x0:
1097
                v_reg_result = ((unsigned short)(mem_data_in >> 16));
1098
                break;
1099
            case 0x2:
1100
                v_reg_result = ((unsigned short)(mem_data_in >> 0));
1101
                break;
1102
            default:
1103
                fprintf (stderr,"Bad mem access @ PC %x (%x)\n", r_pc, mem_offset);
1104
                Fault = 1;
1105
                break;
1106
        }
1107
        break;
1108
 
1109
    case INST_OR32_LWZ: // l.lwz
1110
    case INST_OR32_LWS: // l.lws
1111
        v_reg_result = mem_data_in;
1112
        if (mem_offset != 0)
1113
        {
1114
            fprintf (stderr,"Bad mem access @ PC %x (%x)\n", r_pc, mem_offset);
1115
            Fault = 1;
1116
        }
1117
        break;
1118
 
1119
    default:
1120
        v_reg_result = r_reg_result;
1121
        break;
1122
    }
1123
 
1124
    // Decode instruction to full text?
1125
#ifdef INCLUDE_INST_DUMP    
1126
    if (TRACE_ENABLED(LOG_OR1K))
1127
        or32_instruction_dump(r_pc_last, r_opcode, r_gpr, r_rd_wb, v_reg_result, r_sr);
1128
#endif
1129
 
1130
    // Register writeback required?
1131
    r_reg_rd_out = v_reg_result;
1132
    if (r_rd_wb != 0)
1133
        r_writeback = 1;
1134
 
1135
    // Fetch next instruction
1136
    mem_addr = r_pc;
1137
    mem_data_out = 0;
1138
    mem_rd = 1;
1139
    mem_ifetch = 1;
1140
}
1141
//-----------------------------------------------------------------
1142
// Clock: Execute a single instruction (including load / store)
1143
//-----------------------------------------------------------------
1144
bool OR32::Clock(void)
1145
{
1146
    bool writeback = false;
1147
 
1148
    switch (Cycle)
1149
    {
1150
    // Instruction decode
1151
    case 0:
1152
        Cycle++;
1153
        Decode();
1154
        break;
1155
 
1156
    // Execute
1157
    case 1:
1158
        Cycle++;
1159
        Execute();
1160
        break;
1161
 
1162
    // Writeback & fetch next
1163
    case 2:
1164
        Cycle = 0;
1165
        WriteBack();
1166
        writeback = true;
1167
        break;
1168
    }
1169
 
1170
    // Notify observers if memory write will occur
1171
    if (mem_wr)
1172
    {
1173
        DPRINTF(LOG_MEM, ("MEM: Write Addr %x Value %x Mask %x\n", mem_addr, mem_data_out, mem_wr));
1174
        MonDataStore(mem_addr, mem_wr, mem_data_out);
1175
    }
1176
 
1177
    // Internal Memory?
1178
    int m;
1179
    for (m=0;m<MemRegions;m++)
1180
    {
1181
        if (mem_addr >= MemBase[m] && mem_addr < (MemBase[m] + MemSize[m]))
1182
        {
1183
            TAddress wordAddress = (mem_addr - MemBase[m]) / 4;
1184
            TRegister mem_word = Mem[m][wordAddress];
1185
            mem_word = HTONL(mem_word);
1186
 
1187
            // Write
1188
            switch (mem_wr)
1189
            {
1190
                case 0xF:
1191
                    mem_word = mem_data_out;
1192
                    break;
1193
                case 0x3:
1194
                    mem_data_out &= 0x0000FFFF;
1195
                    mem_word &=~ 0x0000FFFF;
1196
                    mem_word |= mem_data_out;
1197
                    break;
1198
                case 0xC:
1199
                    mem_data_out &= 0xFFFF0000;
1200
                    mem_word &=~ 0xFFFF0000;
1201
                    mem_word |= mem_data_out;
1202
                    break;
1203
                case 0x1:
1204
                    mem_data_out &= 0x000000FF;
1205
                    mem_word &=~ 0x000000FF;
1206
                    mem_word |= mem_data_out;
1207
                    break;
1208
                case 0x2:
1209
                    mem_data_out &= 0x0000FF00;
1210
                    mem_word &=~ 0x0000FF00;
1211
                    mem_word |= mem_data_out;
1212
                    break;
1213
                case 0x4:
1214
                    mem_data_out &= 0x00FF0000;
1215
                    mem_word &=~ 0x00FF0000;
1216
                    mem_word |= mem_data_out;
1217
                    break;
1218
                case 0x8:
1219
                    mem_data_out &= 0xFF000000;
1220
                    mem_word &=~ 0xFF000000;
1221
                    mem_word |= mem_data_out;
1222
                    break;
1223
            }
1224
 
1225
            Mem[m][wordAddress] = HTONL(mem_word);
1226
 
1227
            // Read
1228
            mem_data_in = mem_word;
1229
 
1230
            if (!mem_ifetch)
1231
            {
1232
                if (mem_wr && MemWriteHits[m])
1233
                    MemWriteHits[m][wordAddress]++;
1234
                else if (mem_rd && MemReadHits[m])
1235
                    MemReadHits[m][wordAddress]++;
1236
            }
1237
            else if (MemInstHits[m])
1238
                MemInstHits[m][wordAddress]++;
1239
 
1240
            break;
1241
        }
1242
    }
1243
 
1244
    // External / Peripheral memory
1245
    if (m == MemRegions)
1246
    {
1247
        mem_data_in = PeripheralAccess(mem_addr, mem_data_out, mem_wr, mem_rd);
1248
    }
1249
 
1250
    // Notify observers if memory read has occurred
1251
    if (mem_rd)
1252
    {
1253
        DPRINTF(LOG_MEM, ("MEM: Read Addr %x Value %x\n", mem_addr, mem_data_in));
1254
        MonDataLoad(mem_addr, 0xF, mem_data_in);
1255
    }
1256
 
1257
    // Clock peripherals
1258
    PeripheralClock();
1259
 
1260
    // Writeback (if target is not R0)
1261
    if (r_writeback && r_rd_wb != REG_0_ZERO)
1262
    {
1263
        r_gpr[r_rd_wb] = r_reg_rd_out;
1264
        r_writeback = 0;
1265
    }
1266
 
1267
    // If write-back stage just completed, show register state...
1268
    if (writeback && TRACE_ENABLED(LOG_REGISTERS))
1269
    {
1270
        // Register trace
1271
        int i;
1272
        for (i=0;i<REGISTERS;i+=4)
1273
        {
1274
            printf(" %d: ", i);
1275
            printf(" %08x %08x %08x %08x\n", r_gpr[i+0], r_gpr[i+1], r_gpr[i+2], r_gpr[i+3]);
1276
        }
1277
 
1278
        printf(" SR = 0x%08x, EPC = 0x%08x, ESR = 0x%08x, SR_F=%d\n\n", r_sr, r_epc, r_esr, (r_sr & OR32_SR_F_BIT) ? 1 : 0);
1279
    }
1280
 
1281
    // Reload register contents
1282
    r_reg_ra = r_gpr[r_ra];
1283
    r_reg_rb = r_gpr[r_rb];
1284
 
1285
    return writeback;
1286
}
1287
//-----------------------------------------------------------------
1288
// Step: Step through one instruction
1289
//-----------------------------------------------------------------
1290
bool OR32::Step(void)
1291
{
1292
    while (!Clock())
1293
        ;
1294
    return true;
1295
}
1296
//-----------------------------------------------------------------
1297
// MonNop: Default NOP functions
1298
//-----------------------------------------------------------------
1299
void OR32::MonNop(TRegister imm)
1300
{
1301
    switch (imm)
1302
    {
1303
        // Exit
1304
        case NOP_EXIT:
1305
            exit(r_gpr[NOP_DATA_REG]);
1306
        break;
1307
        // Report value
1308
        case NOP_REPORT:
1309
            if (Trace)
1310 33 ultra_embe
                fprintf(stderr, "0x%x\n", r_gpr[NOP_DATA_REG]);
1311 28 ultra_embe
            else
1312 33 ultra_embe
                printf("0x%x\n", r_gpr[NOP_DATA_REG]);
1313 28 ultra_embe
        break;
1314
        // putc()
1315
        case NOP_PUTC:
1316
            if (EnablePutc)
1317
            {
1318
                if (Trace)
1319
                    fprintf(stderr, "%c", r_gpr[NOP_DATA_REG]);
1320
                else
1321
                    printf("%c", r_gpr[NOP_DATA_REG]);
1322
            }
1323
        break;
1324
        // Trace Control
1325
        case NOP_TRACE_ON:
1326
            Trace = r_gpr[NOP_DATA_REG];
1327
        break;
1328
        case NOP_TRACE_OFF:
1329
            Trace = 0;
1330
        break;
1331
        case NOP_STATS_RESET:
1332
            ResetStats();
1333
        break;
1334
        case NOP_STATS_MARKER:
1335
            StatsMarkers++;
1336
        break;
1337
    }
1338
}
1339
//-----------------------------------------------------------------
1340
// DumpStats: Show execution stats
1341
//-----------------------------------------------------------------
1342
void OR32::DumpStats(void)
1343
{
1344
    printf("Runtime Stats:\n");
1345
    printf("- Total Instructions %d\n", StatsInstructions);
1346
    printf("- Memory Operations %d (%d%%)\n", StatsMem, (StatsMem * 100) / StatsInstructions);
1347 33 ultra_embe
    if (StatsMem != 0)
1348
    {
1349
        printf("  - Reads %d (%d%%)\n", (StatsMem - StatsMemWrites), ((StatsMem - StatsMemWrites) * 100) / StatsMem);
1350
        printf("  - Writes %d (%d%%)\n", StatsMemWrites, (StatsMemWrites * 100) / StatsMem);
1351
    }
1352 28 ultra_embe
    printf("- MUL %d (%d%%)\n", StatsMul, (StatsMul * 100) / StatsInstructions);
1353
    printf("- MULU %d (%d%%)\n", StatsMulu, (StatsMulu * 100) / StatsInstructions);
1354
    printf("- NOPS %d (%d%%)\n", StatsNop, (StatsNop * 100) / StatsInstructions);
1355
    printf("- Markers %d (%d%%)\n", StatsMarkers, (StatsMarkers * 100) / StatsInstructions);
1356
    printf("- Branches Operations %d (%d%%)\n", StatsBranches, (StatsBranches * 100) / StatsInstructions);
1357
    printf("- Exceptions %d (%d%%)\n", StatsExceptions, (StatsExceptions * 100) / StatsInstructions);
1358
 
1359
    FILE *f;
1360
    int i;
1361
    int m;
1362
 
1363
    for (m=0;m<MemRegions;m++)
1364
    {
1365
        if (MemReadHits[m])
1366
        {
1367
            printf("Saving %s\n", MEMTRACE_READS);
1368
            f = fopen(MEMTRACE_READS, "w");
1369
            if (f)
1370
            {
1371
                for (i=0;i<MemSize[m]/4;i++)
1372
                {
1373
                    unsigned int addr = MemBase[m] + (i * 4);
1374
                    if (MemReadHits[m][i] > MEMTRACE_MIN)
1375
                    {
1376
                        fprintf(f, "%08x %d\n", addr, MemReadHits[m][i]);
1377
                    }
1378
                }
1379
                fclose(f);
1380
            }
1381
            else
1382
                fprintf (stderr,"Could not open file for writing\n");
1383
        }
1384
 
1385
        if (MemWriteHits[m])
1386
        {
1387
            printf("Saving %s\n", MEMTRACE_WRITES);
1388
            f = fopen(MEMTRACE_WRITES, "w");
1389
            if (f)
1390
            {
1391
                for (i=0;i<MemSize[m]/4;i++)
1392
                {
1393
                    unsigned int addr = MemBase[m] + (i * 4);
1394
                    if (MemWriteHits[m][i] > MEMTRACE_MIN)
1395
                    {
1396
                        fprintf(f, "%08x %d\n", addr, MemWriteHits[m][i]);
1397
                    }
1398
                }
1399
                fclose(f);
1400
            }
1401
            else
1402
                fprintf (stderr,"Could not open file for writing\n");
1403
        }
1404
 
1405
        if (MemInstHits[m])
1406
        {
1407
            printf("Saving %s\n", MEMTRACE_INST);
1408
            f = fopen(MEMTRACE_INST, "w");
1409
            if (f)
1410
            {
1411
                for (i=0;i<MemSize[m]/4;i++)
1412
                {
1413
                    unsigned int addr = MemBase[m] + (i * 4);
1414
                    if (MemInstHits[m][i] > MEMTRACE_MIN)
1415
                    {
1416
                        fprintf(f, "%08x %d\n", addr, MemInstHits[m][i]);
1417
                    }
1418
                }
1419
                fclose(f);
1420
            }
1421
            else
1422
                fprintf (stderr,"Could not open file for writing\n");
1423
        }
1424
    }
1425
 
1426
    ResetStats();
1427
}

powered by: WebSVN 2.1.0

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