aboutsummaryrefslogtreecommitdiffstats
path: root/src/ymh15/test_mips_ymh15.cpp
blob: 99be82d67b28cc7533808265e6f4405a6929c1b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "test_mips_ymh15.hpp"

// R Type
uint32_t gen_instruction(uint32_t src1, uint32_t src2, uint32_t dest,
                     uint32_t shift, uint32_t function) {
    uint32_t inst = 0;
    inst = inst | src1 << 21 | src2 << 16 | dest << 11 | shift << 6 |
        function;
    return inst;
}

// I Type
uint32_t gen_instruction(uint32_t opcode, uint32_t src, uint32_t dest,
                     uint32_t Astart) {
    uint32_t inst = 0;
    inst = inst | opcode << 26 | src << 21 | dest << 16 | Astart;
    return inst;
}

// J Type
uint32_t gen_instruction(uint32_t opcode, uint32_t memory) {
    uint32_t inst = 0;
    inst = inst | opcode << 26 | memory;
    return inst;
}

void change_endianness(uint32_t &inst) {
    inst = (inst << 24 | ((inst << 8)&0xff0000) |
            ((inst >> 8)&0xff00) |inst >> 24);
}

int check_reg(mips_cpu_h state, uint8_t reg_addr, uint32_t check_value) {
    uint32_t reg;

    if(reg_addr != 255)
        mips_cpu_get_register(state, reg_addr, &reg);
    else
        mips_cpu_get_pc(state, &reg);

    if(reg == check_value)
        return 1;

    printf("Value of reg%d: %#10x\tExpected value: %#10x\n", reg_addr, reg, check_value);
    return 0;
}

int check_error(mips_error err, mips_error expected_err) {
    if(err == expected_err) {
        return 1;
    }

    printf("Received error: %#6x\tExpected error: %#6x\n", err, expected_err);
    return 0;
}

int check_mem(mips_mem_h mem, uint32_t addr, uint32_t length,  uint32_t check_value) {
    uint32_t mem_value = 0;
    mips_mem_read(mem, addr, length, (uint8_t*)&mem_value);
    if(length == 2)
        mem_value = ((mem_value<<8)&0xff00) | mem_value>>8;
    else if(length == 4)
        change_endianness(mem_value);
    if(mem_value == check_value)
        return 1;
    printf("At mem[%#10x]: %#10x\tExpected value: %#10x\n", addr, mem_value, check_value);
    return 0;
}

mips_error set_instruction(mips_mem_h mem, mips_cpu_h state, uint32_t mem_location, uint32_t src1, uint32_t src2, uint32_t dest, uint32_t shift, uint32_t function) {
    uint32_t inst;
    mips_error err;

    rand_reg(state);
    inst = gen_instruction(src1, src2, dest, shift, function);
    change_endianness(inst);
    err = mips_mem_write(mem, mem_location, 4, (uint8_t*)&inst);
    return err;
}

mips_error set_instruction(mips_mem_h mem, mips_cpu_h state, uint32_t mem_location, uint32_t opcode, uint32_t src, uint32_t dest, uint32_t Astart) {
    uint32_t inst;
    mips_error err;

    rand_reg(state);
    inst = gen_instruction(opcode, src, dest, Astart);
    change_endianness(inst);
    err = mips_mem_write(mem, mem_location, 4, (uint8_t*)&inst);
    if(err != mips_Success) {
        printf("couln't write...\n");
    }
    return err;
}

mips_error set_instruction(mips_mem_h mem, mips_cpu_h state, uint32_t mem_location, uint32_t opcode, uint32_t memory) {
    uint32_t inst;
    mips_error err;

    rand_reg(state);
    inst = gen_instruction(opcode, memory);
    change_endianness(inst);
    err = mips_mem_write(mem, mem_location, 4, (uint8_t*)&inst);
    return err;

}

mips_error rand_reg(mips_cpu_h state) {
    mips_error err;
    for(unsigned i = 1; i < 32; ++i) {
        err = mips_cpu_set_register(state, i, rand()%0xffffffff);
        if(err != mips_Success)
            return err;
    }
    return mips_Success;
}