diff options
author | Benedikt Böhm <bb@xnull.de> | 2009-07-07 09:46:27 +0200 |
---|---|---|
committer | Benedikt Böhm <bb@xnull.de> | 2009-07-07 09:46:27 +0200 |
commit | d15276557c65de2a1941632ec9024dea261cce26 (patch) | |
tree | a6a71e24e428f40bf2bdc54d2d4efaf4561786c9 /src | |
parent | b5d10e72de8d93a232886f069db9791b85c3e332 (diff) | |
download | swppy-d15276557c65de2a1941632ec9024dea261cce26.tar.gz swppy-d15276557c65de2a1941632ec9024dea261cce26.tar.xz swppy-d15276557c65de2a1941632ec9024dea261cce26.zip |
make instruction 64-bit wide to support more than 32 registers
Diffstat (limited to 'src')
-rw-r--r-- | src/emu/asm.c | 32 | ||||
-rw-r--r-- | src/emu/asm.h | 4 | ||||
-rw-r--r-- | src/emu/cpu.c | 53 | ||||
-rw-r--r-- | src/emu/cpu.h | 4 | ||||
-rw-r--r-- | src/emu/opc.c | 10 | ||||
-rw-r--r-- | src/emu/opc.h | 19 | ||||
-rw-r--r-- | src/emu/riscas.c | 6 | ||||
-rw-r--r-- | src/emu/risci.c | 26 | ||||
-rw-r--r-- | src/emu/syscall.c | 1 |
9 files changed, 81 insertions, 74 deletions
diff --git a/src/emu/asm.c b/src/emu/asm.c index 4548b48..85f3293 100644 --- a/src/emu/asm.c +++ b/src/emu/asm.c @@ -1,54 +1,52 @@ #include <stdio.h> #include <stdint.h> +#include <inttypes.h> #include "cpu.h" #include "log.h" #include "opc.h" -#define REGa(x) (((x) & 0x1F) << 21) -#define REGb(x) (((x) & 0x1F) << 16) -#define REGc(x) (((x) & 0x1F) << 11) -#define IMMc(x) ((x) & 0xFFFF) +#define REGa(x) (((x) & 0x1FFF) << 45) +#define REGb(x) (((x) & 0x1FFF) << 32) +#define REGc(x) (((x) & 0x1FFF) << 19) +#define IMMc(x) ((x) & 0xFFFFFFFF) -uint32_t compile(const char *line) +inst_t compile(const char *line) { char mnem[5]; - int32_t a = 0, b = 0, c = 0; - static size_t regs = 0; + int64_t a = 0, b = 0, c = 0; /* register file size */ - if (sscanf(line, ".REGS %d", &a) == 1) { - regs = a; + if (sscanf(line, ".REGS %"SCNi64"", &a) == 1) return a; - } /* ADD, SUB, MUL, DIV, MOD, AND, OR */ - if (sscanf(line, "%4s r%d, r%d, r%d", mnem, &a, &b, &c) == 4) + if (sscanf(line, "%4s r%"SCNi64", r%"SCNi64", r%"SCNi64"", mnem, &a, &b, &c) == 4) return mnemonic2opc(mnem) | REGa(a) | REGb(b) | REGc(c); /* LW, SW */ - if (sscanf(line, "%4s r%d, r%d, %d", mnem, &a, &b, &c) == 4) + if (sscanf(line, "%4s r%"SCNi64", r%"SCNi64", %"SCNi64"", mnem, &a, &b, &c) == 4) return mnemonic2opc(mnem) | REGa(a) | REGb(b) | IMMc(c); /* CMP */ - if (sscanf(line, "%4s r%d, r%d", mnem, &a, &b) == 3) + if (sscanf(line, "%4s r%"SCNi64", r%"SCNi64"", mnem, &a, &b) == 3) return mnemonic2opc(mnem) | REGa(a) | REGb(b); /* MOV, BEZ */ - if (sscanf(line, "%4s r%2d, %d", mnem, &a, &c) == 3) + if (sscanf(line, "%4s r%"SCNi64", %"SCNi64"", mnem, &a, &c) == 3) return mnemonic2opc(mnem) | REGa(a) | IMMc(c); /* EQ, NE, LT, LE, GE, GT, PUSH, POP */ - if (sscanf(line, "%4s r%d", mnem, &a) == 2) + if (sscanf(line, "%4s r%"SCNi64"", mnem, &a) == 2) return mnemonic2opc(mnem) | REGa(a); /* JMP, CALL */ - if (sscanf(line, "%4s %d", mnem, &c) == 2) + if (sscanf(line, "%4s %"SCNi64"", mnem, &c) == 2) return mnemonic2opc(mnem) | IMMc(c); /* RET, SYS */ if (sscanf(line, "%4s", mnem) == 1) return mnemonic2opc(mnem); - return 0xFFFFFFFF; + return 0xFFFFFFFFFFFFFFFF; } diff --git a/src/emu/asm.h b/src/emu/asm.h index 9a4fd37..102ae65 100644 --- a/src/emu/asm.h +++ b/src/emu/asm.h @@ -3,6 +3,8 @@ #include <stdint.h> -uint32_t compile(const char *line); +#include "opc.h" + +inst_t compile(const char *line); #endif diff --git a/src/emu/cpu.c b/src/emu/cpu.c index f083283..522e2f2 100644 --- a/src/emu/cpu.c +++ b/src/emu/cpu.c @@ -4,6 +4,7 @@ #include <stdbool.h> #include <signal.h> #include <string.h> +#include <inttypes.h> #include "cpu.h" #include "log.h" @@ -11,7 +12,7 @@ #include "opc.h" #include "syscall.h" -/* stack pointer register*/ +/* stack pointer register */ uint32_t SP; /* base pointer register */ @@ -31,19 +32,19 @@ uint32_t *GPR; /* extract operands from the instruction register */ static inline -uint32_t __OPEXT(uint32_t IR, uint8_t start, uint8_t length) +uint64_t __OPEXT(inst_t IR, uint8_t start, uint8_t length) { - return (IR >> start) & ((1 << length) - 1); + return (IR >> start) & ((1ULL << length) - 1); } #define OPEXT(start, length) __OPEXT(IR, start, length) /* operands */ -#define OPCODE OPEXT(26, 6) -#define REGa OPEXT(21, 5) -#define REGb OPEXT(16, 5) -#define REGc OPEXT(11, 5) -#define IMMc OPEXT(0, 16) +#define OPCODE OPEXT(58, 6) +#define REGa OPEXT(45, 13) +#define REGb OPEXT(32, 13) +#define REGc OPEXT(19, 13) +#define IMMc OPEXT(0, 32) /* cpu traps */ void trap(int num) @@ -67,11 +68,11 @@ void trap(int num) } } -void execute(uint32_t IR) +void execute(inst_t IR) { /* decode op-code */ uint8_t opcode = OPCODE; - int32_t a, b, c; + int64_t a, b, c; if (opcode < OPC_MOV) { /* arithmetic, logic, comparison */ @@ -79,7 +80,7 @@ void execute(uint32_t IR) b = REGb; c = REGc; - debug("IP@%#08x: %-4s r%i, r%i, r%i", IP, + debug("IP@%#08x: %-4s r%"PRIi64", r%"PRIi64", r%"PRIi64, IP, opc2mnemonic(IR), a, b, c); } @@ -90,17 +91,17 @@ void execute(uint32_t IR) c = IMMc; /* sign extension */ - if (c >= 0x8000) - c -= 0x10000; + if (c >= 0x80000000) + c -= 0x100000000; if (opcode < OPC_LW) { - debug("IP@%#08x: %-4s r%i, %i", IP, + debug("IP@%#08x: %-4s r%"PRIi64", %"PRIi64, IP, opc2mnemonic(IR), a, c); } else if (opcode < OPC_PUSH) { - debug("IP@%#08x: %-4s r%i, r%i, %i", IP, + debug("IP@%#08x: %-4s r%"PRIi64", r%"PRIi64", %"PRIi64, IP, opc2mnemonic(IR), a, b, c); } else { - debug("IP@%#08x: %-4s r%i", IP, + debug("IP@%#08x: %-4s r%"PRIi64, IP, opc2mnemonic(IR), a); } } @@ -112,20 +113,20 @@ void execute(uint32_t IR) c = IMMc; /* sign extension */ - if (c >= 0x8000) - c -= 0x10000; + if (c >= 0x80000000) + c -= 0x100000000; switch (opcode) { case OPC_BEZ: - debug("IP@%#08x: %-4s r%i, %i", IP, + debug("IP@%#08x: %-4s r%"PRIi64", %"PRIi64, IP, opc2mnemonic(IR), a, c); break; case OPC_JMP: - debug("IP@%#08x: %-4s %i", IP, + debug("IP@%#08x: %-4s %"PRIi64, IP, opc2mnemonic(IR), c); break; case OPC_CALL: - debug("IP@%#08x: %-4s %i", IP, + debug("IP@%#08x: %-4s %"PRIi64, IP, opc2mnemonic(IR), c); break; case OPC_RET: @@ -215,16 +216,16 @@ void execute(uint32_t IR) break; case OPC_BEZ: if (GPR[a] == 0) { - IP += c * 4; + IP += c * sizeof(inst_t); return; } break; case OPC_JMP: - IP += c * 4; + IP += c * sizeof(inst_t); return; case OPC_CALL: - push(IP + 4); - IP += c * 4; + push(IP + sizeof(inst_t)); + IP += c * sizeof(inst_t); return; case OPC_RET: IP = pop(); @@ -237,5 +238,5 @@ void execute(uint32_t IR) trap(TRP_ILL); } - IP += 4; + IP += sizeof(inst_t); } diff --git a/src/emu/cpu.h b/src/emu/cpu.h index 4867a8a..9294d7d 100644 --- a/src/emu/cpu.h +++ b/src/emu/cpu.h @@ -4,6 +4,8 @@ #include <stdint.h> #include <stdbool.h> +#include "opc.h" + /* cpu traps */ enum { TRP_UNALIGNED, @@ -33,6 +35,6 @@ extern bool N, Z; extern uint32_t *GPR; /* main cpu execution function */ -void execute(uint32_t IR); +void execute(inst_t IR); #endif diff --git a/src/emu/opc.c b/src/emu/opc.c index 3d62479..c9e5f8c 100644 --- a/src/emu/opc.c +++ b/src/emu/opc.c @@ -5,7 +5,7 @@ typedef struct opc_mapping { const char *name; - uint32_t opcode; + inst_t opcode; } opc_mapping_t; opc_mapping_t opc_map[] = { @@ -36,19 +36,19 @@ opc_mapping_t opc_map[] = { { NULL, 0 } }; -uint32_t mnemonic2opc(const char *mnemonic) +inst_t mnemonic2opc(const char *mnemonic) { for (uint8_t i = 0; opc_map[i].name; i++) { if (strcmp(opc_map[i].name, mnemonic) == 0) - return opc_map[i].opcode << 26; + return opc_map[i].opcode << 58; } return ~0; } -const char *opc2mnemonic(uint32_t IR) +const char *opc2mnemonic(inst_t IR) { - uint32_t opcode = IR >> 26; + inst_t opcode = IR >> 58; for (uint8_t i = 0; opc_map[i].name; i++) { if (opc_map[i].opcode == opcode) diff --git a/src/emu/opc.h b/src/emu/opc.h index 179f7b2..8720958 100644 --- a/src/emu/opc.h +++ b/src/emu/opc.h @@ -7,17 +7,17 @@ * --------------------- * * arithmetic: - * |000|xxx|aaaaa|bbbbb|ccccc|00000000000| + * |000|xxx|aaaaaaaaaaaaa|bbbbbbbbbbbbb|ccccccccccccc|0000000000000000000| * logic: - * |001|xxx|aaaaa|bbbbb|ccccc|00000000000| + * |001|xxx|aaaaaaaaaaaaa|bbbbbbbbbbbbb|ccccccccccccc|0000000000000000000| * comparison: - * |010|xxx|aaaaa|bbbbb|0000000000000000| + * |010|xxx|aaaaaaaaaaaaa|bbbbbbbbbbbbb|00000000000000000000000000000000| * load & store: - * |011|xxx|aaaaa|bbbbb|cccccccccccccccc| + * |011|xxx|aaaaaaaaaaaaa|bbbbbbbbbbbbb|cccccccccccccccccccccccccccccccc| * jump: - * |100|xxx|aaaaa|00000|cccccccccccccccc| + * |100|xxx|aaaaaaaaaaaaa|0000000000000|cccccccccccccccccccccccccccccccc| * misc: - * |111|xxx|??????????????????????????| + * |111|xxx|??????????????????????????????????????????????????????????| * */ @@ -57,8 +57,11 @@ /* misc */ #define OPC_SYS 070 +/* one instruction is 64 bit */ +typedef uint64_t inst_t; + /* conversion functions */ -uint32_t mnemonic2opc(const char *mnemonic); -const char *opc2mnemonic(uint32_t IR); +inst_t mnemonic2opc(const char *mnemonic); +const char *opc2mnemonic(inst_t IR); #endif diff --git a/src/emu/riscas.c b/src/emu/riscas.c index 7a4af47..5b6cac9 100644 --- a/src/emu/riscas.c +++ b/src/emu/riscas.c @@ -28,12 +28,12 @@ int main(int argc, char *argv[]) char line[128]; while (fgets(line, 128, sfd)) { - uint32_t IR = compile(line); + inst_t IR = compile(line); - if (IR == 0xFFFFFFFF) + if (IR == 0xFFFFFFFFFFFFFFFF) die("illegal instruction: %s", line); - fwrite(&IR, 4, 1, pfd); + fwrite(&IR, sizeof(inst_t), 1, pfd); } return 0; diff --git a/src/emu/risci.c b/src/emu/risci.c index 704ece8..1711089 100644 --- a/src/emu/risci.c +++ b/src/emu/risci.c @@ -17,8 +17,8 @@ #include "opc.h" bool is_debug = false; -size_t mem_size = 64 * 1024 * 1024; -size_t reg_size = 0; +uint64_t mem_size = 64 * 1024 * 1024; +uint64_t reg_size = 0; static void usage(int rc) @@ -42,17 +42,17 @@ void read_program(const char *program) if (lstat(program, &sb) == -1) pdie("cannot stat program"); - if (sb.st_size % 4) - die("program does not align to op-code size of 4 bytes"); + if (sb.st_size % sizeof(inst_t)) + die("program does not align to instruction size of %zu bytes", sizeof(inst_t)); int pfd; if ((pfd = open(program, O_RDONLY)) == -1) pdie("could not open program"); /* initialize register file */ - assert(read(pfd, ®_size, 4) == 4); + assert(read(pfd, ®_size, sizeof(inst_t)) == sizeof(inst_t)); reg_size += 4; - GPR = calloc(reg_size, 4); + GPR = calloc(reg_size, sizeof(uint32_t)); /* initialize pseudo registers */ BP = reg_size - 3; @@ -61,15 +61,15 @@ void read_program(const char *program) GPR[BP] = GPR[SP] = mem_size; GPR[RV] = 0; - assert(read(pfd, MEM, sb.st_size - 4) == sb.st_size - 4); - memset(MEM + sb.st_size + 4, 0xFF, 4); + assert(read(pfd, MEM, sb.st_size - sizeof(inst_t)) == (ssize_t)(sb.st_size - sizeof(inst_t))); + memset(MEM + sb.st_size, 0xFF, sizeof(inst_t)); } static -uint32_t next_instruction(void) +inst_t next_instruction(void) { - uint32_t tmp; - memcpy(&tmp, &MEM[IP], 4); + inst_t tmp; + memcpy(&tmp, &MEM[IP], sizeof(inst_t)); return tmp; } @@ -85,7 +85,7 @@ int main(int argc, char *argv[]) case 'h': usage(EXIT_SUCCESS); case 'm': - mem_size = atoi(optarg) * 4; + mem_size = atoi(optarg) * sizeof(uint32_t); break; case '?': default: @@ -97,7 +97,7 @@ int main(int argc, char *argv[]) argv += optind; /* reserve memory */ - MEM = calloc(mem_size, sizeof(char)); + MEM = calloc(mem_size, sizeof(uint8_t)); /* load program from file */ if (argc < 1) diff --git a/src/emu/syscall.c b/src/emu/syscall.c index aba3448..92cab22 100644 --- a/src/emu/syscall.c +++ b/src/emu/syscall.c @@ -1,5 +1,6 @@ #include <unistd.h> #include <stdlib.h> +#include <stdio.h> #include <inttypes.h> #include "cpu.h" |