From 7bb67e8e53ae008c0c028667d34b76ade164e596 Mon Sep 17 00:00:00 2001 From: cth103 Date: Thu, 7 Jun 2018 17:35:25 +0000 Subject: [PATCH] add opcodes from before --- arm/cpu.c | 510 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 488 insertions(+), 22 deletions(-) diff --git a/arm/cpu.c b/arm/cpu.c index aeba8e3..f24e152 100644 --- a/arm/cpu.c +++ b/arm/cpu.c @@ -1,31 +1,62 @@ #include "cpu_definitions.h" #include - /* CPU Status flags */ uint64_t N = 0x00000000; //Negative uint64_t Z = 0x00000000; //Zero uint64_t C = 0x00000000; //Carry (or Unsigned Overflow) uint64_t V = 0x00000000; //Overflow (Signed) - +uint64_t opcode; uint64_t PC = 0x00000000; //Program Counter -uint64_t *MEMORY; //Memory +int isRunning; +uint64_t *mem; //mem + +void mem_writeData(uint64_t *data) { + uint64_t despacito = 0x00000000; + uint64_t dametucosita = 0x00000000; + while(sizeof(despacito) < sizeof(data)) { + mem[despacito] = data[dametucosita]; + despacito = despacito + 0x01; + dametucosita = dametucosita + 0x01; + } +} + +void mem_write(uint64_t addr, uint64_t value) { + mem[addr] = value; +} + +uint64_t mem_read(uint64_t addr) { + return mem[addr]; +} + +void start_cpu() { //Start emulating the CPU + isRunning = 1; + while(isRunning == 1) { + opcode = mem[PC]; //fetch opcode + interpret(opcode); //interpret opcode + } +} -void interpret(uint64_t opcode) { +void stop_cpu() { //Stop emulating the CPU + isRunning = 0; +} + +void interpret(uint64_t opcode) { /* emulate opcode */ switch(opcode) { //ADC (Add with Carry) + /* Add/subtract (with carry). */ case 0x1a000000: - MEMORY[pc+1] = MEMORY[pc+2] + MEMORY[pc+3] + C; + mem[pc+1] = mem[pc+2] + mem[pc+3] + C; //dest = op_1 + op_2 + Carry - if (MEMORY[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? C = 0x00000001; pc = pc + 1; break; } - if (MEMORY[pc+1] < 0x00000000) { //negative? + if (mem[pc+1] < 0x00000000) { //negative? N = 0x00000001; pc = pc + 1; break; } - if (MEMORY[pc+1] = 0x00000000) { //zero? + if (mem[pc+1] = 0x00000000) { //zero? Z = 0x00000001; pc = pc + 1; break; @@ -33,18 +64,18 @@ void interpret(uint64_t opcode) { pc = pc + 1; break; case 0x3a000000: //ADCS (Add with Carry With Status) - MEMORY[pc+1] = MEMORY[pc+2] + MEMORY[pc+3] + C; - if (MEMORY[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + mem[pc+1] = mem[pc+2] + mem[pc+3] + C; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? C = 0x00000001; pc = pc + 1; break; } - if (MEMORY[pc+1] < 0x00000000) { //negative? + if (mem[pc+1] < 0x00000000) { //negative? N = 0x00000001; pc = pc + 1; break; } - if (MEMORY[pc+1] = 0x00000000) { //zero? + if (mem[pc+1] = 0x00000000) { //zero? Z = 0x00000001; pc = pc + 1; break; @@ -53,18 +84,38 @@ void interpret(uint64_t opcode) { pc = pc + 1; break; case 0x5a000000: //SBC (Subtract with Carry) - MEMORY[pc+1] = MEMORY[pc+2] - MEMORY[pc+3] - ~C; - if (MEMORY[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + mem[pc+1] = mem[pc+2] - mem[pc+3] - ~C; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 - op_2 - NOT(Carry) + pc = pc + 1; + break; + case 0x7a000000: //SBCS (Subtract with Carry With Status) + mem[pc+1] = mem[pc+2] - mem[pc+3] - ~C; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? C = 0x00000001; pc = pc + 1; break; } - if (MEMORY[pc+1] < 0x00000000) { //negative? + if (mem[pc+1] < 0x00000000) { //negative? N = 0x00000001; pc = pc + 1; break; } - if (MEMORY[pc+1] = 0x00000000) { //zero? + if (mem[pc+1] = 0x00000000) { //zero? Z = 0x00000001; pc = pc + 1; break; @@ -72,19 +123,19 @@ void interpret(uint64_t opcode) { //dest = op_1 - op_2 - NOT(Carry) pc = pc + 1; break; - case 0x7a000000: //SBC (Subtract with Carry With Status) - MEMORY[pc+1] = MEMORY[pc+2] - MEMORY[pc+3] - ~C; - if (MEMORY[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + case 0x5a0003e0: //NGC (Negate with Carry) (This instruction is an alias of SBC.) + mem[pc+1] = mem[pc+2] - mem[pc+3] - ~C; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? C = 0x00000001; pc = pc + 1; break; } - if (MEMORY[pc+1] < 0x00000000) { //negative? + if (mem[pc+1] < 0x00000000) { //negative? N = 0x00000001; pc = pc + 1; break; } - if (MEMORY[pc+1] = 0x00000000) { //zero? + if (mem[pc+1] = 0x00000000) { //zero? Z = 0x00000001; pc = pc + 1; break; @@ -92,5 +143,420 @@ void interpret(uint64_t opcode) { //dest = op_1 - op_2 - NOT(Carry) pc = pc + 1; break; + case 0x7a0003e0: //NGCS (Negate with Carry With Status) (This instruction is an alias of SBCS.) + mem[pc+1] = mem[pc+2] - mem[pc+3] - ~C; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 - op_2 - NOT(Carry) + pc = pc + 1; + break; + /* Add/subtract (extended register). */ + case 0x0b200000: //ADD (adds...) + mem[pc+1] = mem[pc+2] + mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 + op_2 + pc = pc + 1; + break; + case 0x2b200000: //ADDS (adds With Status) + mem[pc+1] = mem[pc+2] + mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 + op_2 + pc = pc + 1; + break; + case 0x2b20001f: //CMN (Compare Negative) + N = mem[pc+2] - ~mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)?C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + // = op_1 - (NOT op_2) ; result is not stored, only flags updated + pc = pc + 1; + break; + case 0x4b200000: //SUB (substracts) + mem[pc+1] = mem[pc+2] - mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 - op_2 + pc = pc + 1; + break; + case 0x6b200000: //SUBS (substracts with status) + mem[pc+1] = mem[pc+2] - mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 - op_2 + pc = pc + 1; + break; + case 0x6b20001f: //CMP (COMPARE) + N = mem[pc+2] - mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + // = op_1 - op_2 ; result is not stored, only flags updated + pc = pc + 1; + break; + + /* Add/subtract (immediate). */ + case 0x11000000: //ADD (adds...) + mem[pc+1] = mem[pc+2] + mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 + op_2 + pc = pc + 1; + break; + + case 0x11000000: // mov ( moves ) + mem[pc+1] = mem[pc+2]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 + pc = pc + 1; + break; + case 0x31000000: //ADD (adds...) + mem[pc+1] = mem[pc+2] + mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 + op_2 + pc = pc + 1; + break; + case 0x3100001f: //CMN (Compare Negative) + N = mem[pc+2] - ~mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + // = op_1 - (NOT op_2) ; result is not stored, only flags updated + pc = pc + 1; + break; + case 0x51000000: //SUB (substracts) + mem[pc+1] = mem[pc+2] - mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 - op_2 + pc = pc + 1; + break; + case 0x71000000: //SUBS (substracts with flags) + mem[pc+1] = mem[pc+2] - mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 - op_2 + pc = pc + 1; + break; + case 0x7100001f: //CMP (COMPARE) + N = mem[pc+2] - mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + // = op_1 - op_2 ; result is not stored, only flags updated + pc = pc + 1; + break; + /* Add/subtract (shifted register). */ + case 0x0b000000: //ADD (adds...) + mem[pc+1] = mem[pc+2] + mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 + op_2 + pc = pc + 1; + break; + case 0x2b000000: //ADDS (adds... WITH STATUSES) + mem[pc+1] = mem[pc+2] + mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 + op_2 + pc = pc + 1; + break; + case 0x2b00001f: //CMN (Compare Negative) + N = mem[pc+2] - ~mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + // = op_1 - (NOT op_2) ; result is not stored, only flags updated + pc = pc + 1; + break; + case 0x4b000000: //SUB (substracts) + mem[pc+1] = mem[pc+2] - mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 - op_2 + pc = pc + 1; + break; + case 0x4b0003e0: //NEG (negates) + mem[pc+1] = -mem[pc+2]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 - op_2 + pc = pc + 1; + break; + case 0x6b00001f: //SUBS (substracts with statuses) + mem[pc+1] = mem[pc+2] - mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 - op_2 + pc = pc + 1; + break; + case 0x6b20001f: //CMPS (COMPARE WITH STATUSES) + N = mem[pc+2] - mem[pc+3]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + // = op_1 - op_2 ; result is not stored, only flags updated + pc = pc + 1; + break; + case 0x6b0003e0: //NEGS (negates with statuses) + mem[pc+1] = -mem[pc+2]; + if (mem[pc+1] => 0xffffffff) { //overflow (unsigned signed)? + C = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] < 0x00000000) { //negative? + N = 0x00000001; + pc = pc + 1; + break; + } + if (mem[pc+1] = 0x00000000) { //zero? + Z = 0x00000001; + pc = pc + 1; + break; + } + //dest = op_1 - op_2 + pc = pc + 1; + break; + /* TODO: add AdvSIMD instructions */ } -} +} \ No newline at end of file -- 2.11.4.GIT