Commit dc021ed2 authored by sea19's avatar sea19
Browse files

Fetch and decode functioning

parents 442454c2 0163139f
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/
<?xml version="1.0" encoding="UTF-8"?>
<module type="CPP_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/arm11_47.iml" filepath="$PROJECT_DIR$/.idea/arm11_47.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
int *readFile(char *filename) {
int *objectCode = calloc(16384, sizeof(int)); //Creates a pointer with allocated space of 64KB
int i = 0;
FILE *ptr = fopen(filename, "rb"); //Opens file "filename" to be read as a binary file
assert(ptr != NULL); //Checks the file has been read
while (!feof(ptr)) {
fread(objectCode + i, 4, 1, ptr); //Stores the binary data in the files into the array objectCode
i++;
}
fclose(ptr); //Closes file "filename"
return objectCode;
}
#define NREGS 17
#define STACK_SIZE 16384 //Defined stack as in5ts which are 4 bytes so (64*1024)/4
#define PC 15
int fetch(int *objectcode, int programCounter) {
return objectcode[programCounter]; //Returns an instruction at the value of programCounter
}
typedef struct decoded {
enum type{and, eor, sub, rsb, add, tst, teq, cmp, orr, mov, multiply, branch, singledata}type;
unsigned int condition;
unsigned int bit0to25;
} decoded;
/*typedef struct arm_state {
unsigned int regs[NREGS];
unsigned int *memory;
int n, z, c, v;
} armstate; */
// for tests and analysis
/*struct emu_analysis_struct {
unsigned int regs_write[NREGS];
unsigned int regs_read[NREGS];
int num_instructions_ex;
int data_processing;
int memory;
int branches_taken;
int branches_not_taken;
};*/
void initialiseRegisters(int *registers) {
for (int i = 0; i < 17; i++) {
registers[i] = 0; //Sets all the registers to 0
}
char *printenum(enum type t) { //Testing
switch(t) {
case and:
return "and";
break;
case eor:
return "eor";
break;
case sub:
return "sub";
break;
case rsb:
return "rsb";
break;
case add:
return "add";
break;
case tst:
return "tst";
break;
case teq:
return "cmp";
break;
case cmp:
return "cmp";
break;
case orr:
return "orr";
break;
case mov:
return "mov";
break;
case multiply:
return "mul";
break;
case branch:
return "branch";
break;
case singledata:
return "singledata";
break;
}
return "NULL";
}
void decode(int instruction, int programcounter) { //Decode started but not working yet
enum instrSet{dataProcess, mul, singleData, branch};
enum instrSet instrType;
int bit26and27 = 134217728 + 67108864;
void findOpcode(decoded *decodedInstr, unsigned int instruction) {
unsigned int opcode = (instruction >> 21) & 0xf;
if ((bit26and27 & instruction) == 0) {
instrType = dataProcess;
} else if ((bit26and27 & instruction) == 67108864) {
instrType = singleData;
} else if ((bit26and27 & instruction) == 134217728) {
instrType = branch;
if (opcode == 0) {
decodedInstr->type = and;
} else if (opcode == 1) {
decodedInstr->type = eor;
} else if (opcode == 2) {
decodedInstr->type = sub;
} else if (opcode == 3) {
decodedInstr->type = rsb;
} else if (opcode == 4) {
decodedInstr->type = add;
} else if (opcode == 8) {
decodedInstr->type = tst;
} else if (opcode == 9) {
decodedInstr->type = teq;
} else if (opcode == 10) {
decodedInstr->type = cmp;
} else if (opcode == 12) {
decodedInstr->type = orr;
} else if (opcode == 13) {
decodedInstr->type = mov;
}
}
void decode(unsigned int instruction, decoded *decodedInstr) {
unsigned int bit26and27 = (instruction >> 26) & 0b11;
decodedInstr->condition = (instruction >> 28) & 0xf;
decodedInstr->bit0to25 = (instruction) & 0x3ffffff;
/*switch (instrType) {
case dataProcess:
decodeDataProcess(instruction, programcounter);
break;
}*/
if (bit26and27 == 0) {
findOpcode(decodedInstr, instruction);
} else if (bit26and27 == 1) {
decodedInstr->type = singledata;
} else if (bit26and27 == 2) {
decodedInstr->type = branch;
}
}
void decodeBranch(int instruction, int pc) {
int cond = (instruction & -268435456) / 26843546;
printf("%d\n", cond);
unsigned int fetch(unsigned int *objectcode, unsigned int programCounter) {
return objectcode[programCounter]; //Returns an instruction at the value of programCounter
}
/*void decodeDataProcess(int instruction, int pc, char* decodedData) {
int opcode = ((2^24 + 2^23 + 2^22 + 2^21) & instruction) / (2^21)
switch (opcode) {
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 8:
break;
case 9:
break;
case 10:
break;
case 12:
break;
case 13:
break;
void startCycle(unsigned int *objectcode, unsigned int *registers) {
unsigned int pc = registers[PC]; //pc takes the value of the program counter
unsigned int fetched;
decoded *decodedInstr = calloc(1, sizeof(decoded));
}
}*/
void startCycle(int *objectcode, int *registers) {
int pc = registers[15]; //pc takes the value of the program counter
int fetchedInstr = NULL;
char *decodedInstr = NULL;
for (int i = 0; i < 3; i++) {
if (pc == 0) {
fetchedInstr = fetch(objectcode, pc);
pc = pc + 4;
} else if (pc == 4) {
decode(objectcode, (pc/4 - 1));
fetch(objectcode, pc/4);
pc = pc + 4;
fetched = fetch(objectcode, pc);
pc = pc + 1;
} else if (pc == 1) {
decode(fetched, decodedInstr);
fetched = fetch(objectcode, pc);
pc = pc + 1;
} else {
//execute(objectcode, (pc/4 - 2));
decode(objectcode, (pc/4 - 1));
fetch(objectcode, pc/4);
decode(objectcode, (pc/4 - 1));
pc = pc + 4;
//execute(decodedInstr);
decode(fetched, decodedInstr);
fetched = fetch(objectcode, pc);
pc = pc + 1;
}
printf("fetched instruction: %d\n", fetched);
printf("decoded type: %s\n", printenum(decodedInstr->type)); //Used for testing
}
free(decodedInstr);
}
int main(int argc, char **argv) {
unsigned int *readFile(char *filename) {
unsigned int *objectCode = calloc(16384, sizeof(int));
//Creates a pointer with allocated space of 64KB
int i = 0;
FILE *ptr = fopen(filename, "rb"); //Opens file "filename" to be read as a binary file
assert(ptr != NULL); //Checks the file has been read
int registers[17];
int *objectcode;
char *decodedData;
bool halt;
while (!feof(ptr)) {
fread(objectCode + i, 4, 1, ptr);
//Stores the binary data in the files into the array objectCode
i++;
}
fclose(ptr); //Closes file "filename"
return objectCode;
}
int main(int argc, char **argv) {
unsigned int *objectcode = calloc(STACK_SIZE, sizeof(int));
unsigned int registers[NREGS];
for (int i = 0; i < NREGS; i++) {
registers[i] = 0;
}
assert(argc == 2);
initialiseRegisters(&registers[0]);
objectcode = readFile(argv[1]);
while (!halt) {
startCycle(objectCode, &registers[0]);
}
startCycle(objectcode, registers);
printf("%d\n", fetch(objectcode, 0));
free(objectcode);
return EXIT_SUCCESS;
}
// finished Single Data Transfer instructions,
// did part of the data processing instructions,
// haven't done any test yet
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define NREGS 16
#define STACK_SIZE 1024
#define PC 15
struct arm_state {
unsigned int regs[NREGS];
unsigned char memory_stack[STACK_SIZE];
int n, z, k, v;
};
// for tests and analysis
struct emu_analysis_struct {
unsigned int regs_write[NREGS];
unsigned int regs_read[NREGS];
int num_instructions_ex;
int data_processing;
int memory;
int branches_taken;
int branches_not_taken;
};
void set_flag(int n, int z, int k, int v, struct arm_state *state) {
state -> n = n;
state -> z = z;
state -> k = k;
state -> v = v;
}
// next_instruction_condition_check
int do_next_instruction(struct arm_state *state, struct emu_analysis_struct *analysis){
unsigned int ni = *((unsigned int *) state -> regs[PC]);
unsigned int cond = (ni >> 28) & 0xF;
int run_command;
if ((cond == 0) && (state->z == 1 )) { // cond in decimal?
run_command = 1;
} else if ((cond == 1) && (state->z == 0)) {
run_command = 1;
} else if ((cond == 10) && (state->n == state->v)) {
run_command = 1;
} else if ((cond == 11) && (state->n != state->v)) {
run_command = 1;
} else if (cond == 12 && state->z == 0 && state->n == state->v) {
run_command = 1;
} else if (cond == 13 && (state->z == 1 || state->n != state->v)) {
run_command = 1;
} else if (cond == 14){
run_command = 1;
} else {
run_command = 0;
}
return run_command;
}
//Operand2 is a register
unsigned int val_reg_last12bits(unsigned int iw, struct emu_analysis_struct *analysis) {
unsigned int val_in_rm = analysis->regs_read[iw & 0xF]; // regs_read[iw & 0xF] == Rm
unsigned int sh_op = (iw >> 4) & 0b1;
unsigned int sh_type = (iw >> 5) & 0b11;
unsigned int amount;
if(sh_op == 0){
amount = (iw >> 7) & 0b11111;
}else{
amount = analysis->regs_write[iw >> 8 & 0xF];
}
//how_to_shift(sh_type, amount, val_in_rm)
switch (sh_type) {
case 0 : val_in_rm << amount;
break;
case 1 : val_in_rm >> amount;
break;
case 2 : (signed) val_in_rm >> amount;
break;
case 3 : (signed) val_in_rm << amount;
break;
default :
exit(1);
}
return val_in_rm;
}
void data_processing_instr(struct arm_state *state, struct emu_analysis_struct *analysis){
unsigned int operand2, immediate, iw, opCode, rd, rn;
iw = *((unsigned int *) state->regs[PC]);
immediate = (iw >> 25) & 0b1;
opCode = (iw >> 21) & 0xF;
rd = (iw >> 12) & 0xF;
rn = (iw >> 16) & 0xF;
if(immediate == 1){
operand2 = ((iw & 0xFF) << 0xF) || (((iw >> 8) & 0xF) >> 0xFF); // ?????????
} else{
operand2 = val_reg_last12bits(iw, analysis);
}
switch (opCode) {
case 0 : state -> regs[rd] = (state -> regs[rn] & operand2) ;
break;
case 1 : ;
break;
case 2 : state -> regs[rd] = state -> regs[rn] = operand2 ;
break;
case 3 : ;
break;
case 4 : ;
break;
case 8 : ;
break;
case 9 : ;
break;
case 10 : ;
break;
case 12 : ;
break;
case 13 : ;
break;
default :
exit(1);
}
}
void single_data_transfer_instr(struct arm_state *state, struct emu_analysis_struct *analysis){
unsigned int iw, immediate, offset, p_index, up_bit, load_bit, rn, rd;
unsigned int data;
iw = *((unsigned int *) state->regs[PC]);
immediate = (iw >> 25) & 0b1;//0 - 24 bits 没了(第二十五位
p_index = (iw >> 24) & 0b1;
up_bit = (iw >> 23) & 0b1;
load_bit = (iw >> 20) & 0b1;
rn = (iw >> 16) & 0xF;
rd = (iw >> 12) & 0xF;
//calculate the offset
if (immediate == 0) {
offset = iw & 0xFFF;
} else {
// Operand2 is a register, return the value of offset / op2
offset = val_reg_last12bits(iw, analysis);
}
if(load_bit == 1) {
data = *((unsigned int *) state->memory_stack[rn]);
*((unsigned int *) state -> regs[rn]) = data;
}
if(p_index == 1){
analysis -> regs_read[rn] = state -> regs[rn];
if(up_bit == 1){
analysis -> regs_read[rn] += offset;
} else{
analysis -> regs_read[rn] -= offset;
}
state -> regs[rd] = analysis -> regs_read[rn];
} else{
if(up_bit == 1){
state -> regs[rn] += offset;
} else{
state -> regs[rn] -= offset;
}
state -> regs[rd] = state -> regs[rn];
}
}
void multiply_instr(struct arm_state *state, struct emu_analysis_struct *analysis){
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment