cpu-sr32.c (3044B)
1 // Copyright 2025, Brian Swetland <swetland@frotz.net> 2 // Licensed under the Apache License, Version 2.0. 3 4 #include <stdio.h> 5 #include <unistd.h> 6 7 #include <emulator-sr32.h> 8 9 #define WITH_TRACE 1 10 11 void sr32core(CpuState *s) { 12 int32_t a, b, n; 13 uint32_t pc = s->pc; 14 for (;;) { 15 int32_t ins = mem_rd32(pc); 16 #if WITH_TRACE 17 if (s->flags & F_TRACE_FETCH) { 18 fprintf(stderr,"%08x %08x\n", pc, ins); 19 } 20 #endif 21 pc += 4; 22 switch ((ins >> 3) & 7) { 23 case 0b000: 24 case 0b001: 25 case 0b010: 26 case 0b011: // I/R 27 a = s->r[(ins >> 11) & 31]; 28 b = ins >> 16; 29 if (ins & 0b010000) b = s->r[b & 31]; 30 switch (ins & 15) { 31 case 0x0: n = a + b; break; 32 case 0x1: n = a - b; break; 33 case 0x2: n = a & b; break; 34 case 0x3: n = a | b; break; 35 case 0x4: n = a ^ b; break; 36 case 0x5: n = a << (b & 31); break; 37 case 0x6: n = ((uint32_t)a) >> (b & 31); break; 38 case 0x7: n = a >> (b & 31); break; 39 case 0x8: n = (a < b) ? 1 : 0; break; 40 case 0x9: n = (((uint32_t)a) < ((uint32_t)b)) ? 1 : 0; break; 41 case 0xa: n = a * b; break; 42 case 0xb: n = a / b; break; 43 case 0xf: n = pc; pc = a + b; break; 44 default: goto undef; 45 } 46 b = (ins >> 6) & 31; 47 if (b) { 48 s->r[b] = n; 49 #if WITH_TRACE 50 if (s->flags & F_TRACE_REGS) { 51 fprintf(stderr,"%08x -> X%d\n", n, b); 52 } 53 #endif 54 } 55 break; 56 case 0b100: // L 57 a = s->r[(ins >> 11) & 31] + (ins >> 16); 58 switch (ins & 7) { 59 case 0: n = mem_rd32(a); break; 60 case 1: n = mem_rd16(a); if (n & 0x8000) n |= 0xFFFF0000; break; 61 case 2: n = mem_rd8(a); if (n & 0x80) n |= 0xFFFFFF00; break; 62 case 3: n = io_rd32(s, a); break; 63 case 4: n = ins & 0xFFFF0000; break; 64 case 5: n = mem_rd16(a); break; 65 case 6: n = mem_rd8(a); break; 66 case 7: n = pc + (ins & 0xFFFF0000); break; 67 } 68 b = (ins >> 6) & 31; 69 if (b) { 70 s->r[b] = n; 71 #if WITH_TRACE 72 if (s->flags & F_TRACE_REGS) { 73 fprintf(stderr,"%08x -> X%d\n", n, b); 74 } 75 #endif 76 } 77 break; 78 case 0b101: // S 79 a = s->r[(ins >> 11) & 31] + (ins >> 16); 80 b = s->r[(ins >> 6) & 31]; 81 switch (ins & 7) { 82 case 0: mem_wr32(a, b); break; 83 case 1: mem_wr16(a, b); break; 84 case 2: mem_wr8(a, b); break; 85 case 3: io_wr32(s, a, b); break; 86 default: goto undef; 87 } 88 break; 89 case 0b110: // B 90 a = s->r[(ins >> 11) & 31]; 91 b = s->r[(ins >> 6) & 31]; 92 switch (ins & 7) { 93 case 0: n = (a == b); break; 94 case 1: n = (a != b); break; 95 case 2: n = (a < b); break; 96 case 3: n = (((uint32_t)a) < ((uint32_t)b)); break; 97 case 4: n = (a >= b); break; 98 case 5: n = (((uint32_t)a) >= ((uint32_t)b)); break; 99 default: goto undef; 100 } 101 if (n) pc = pc + (ins >> 16); 102 break; 103 case 0b111: // J 104 switch (ins & 7) { 105 case 0: 106 a = ins >> 11; 107 b = (ins >> 6) & 31; 108 if (b) s->r[b] = pc; 109 pc = pc + a; 110 break; 111 case 1: s->pc = pc; do_syscall(s, ins >> 11); break; 112 //case 1: s->xpc = pc; pc = s->vec_syscall; break; 113 //case 2: s->xpc = pc; pc = s->vec_break; break; 114 //case 3: pc = s->xpc; 115 default: /* undefined instruction */ 116 undef: 117 s->pc = pc; 118 do_undef(s, ins); 119 return; 120 //s->xpc = pc; pc = s->vec_undef; 121 } 122 break; 123 } 124 } 125 } 126