aboutsummaryrefslogtreecommitdiff
path: root/qtmips_gui/registersdock.cpp
blob: d9d3f2fecf28c28387dc93ccdf7a1afe3d1ddf41 (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
115
116
#include "registersdock.h"

static const QString labels[] = {
    "zero",
    "at",
    "v0",
    "v1",
    "a0",
    "a1",
    "a2",
    "a3",
    "t0",
    "t1",
    "t2",
    "t3",
    "t4",
    "t5",
    "t6",
    "t7",
    "s0",
    "s1",
    "s2",
    "s3",
    "s4",
    "s5",
    "s6",
    "s7",
    "t8",
    "t9",
    "k0",
    "k1",
    "gp",
    "sp",
    "fp",
    "ra"
};

RegistersDock::RegistersDock(QWidget *parent) : QDockWidget(parent) {
    scrollarea = new QScrollArea(this);
    scrollarea->setWidgetResizable(true);
    widg = new StaticTable(scrollarea);

#define INIT(X, LABEL) do{ \
        X = new QLabel("0x00000000", widg); \
        X->setFixedSize(X->sizeHint()); \
        X->setText(""); \
        X->setTextInteractionFlags(Qt::TextSelectableByMouse); \
        widg->addRow({new QLabel(LABEL, widg), X}); \
    } while(false)

    for (int i = 0; i < 32; i++)
        INIT(gp[i], QString("$") + QString::number(i) + QString("/") + labels[i]);
    INIT(pc, "pc");
    INIT(lo, "lo");
    INIT(hi, "hi");
#undef INIT
    scrollarea->setWidget(widg);

    setWidget(scrollarea);
    setObjectName("Registers");
    setWindowTitle("Registers");
}

RegistersDock::~RegistersDock() {
    delete pc;
    delete hi;
    delete lo;
    for (int i = 0; i < 32; i++)
        delete gp[i];
    delete widg;
    delete scrollarea;
}

void RegistersDock::setup(machine::QtMipsMachine *machine) {
    if (machine == nullptr) {
        // Reset data
        pc->setText("");
        hi->setText("");
        lo->setText("");
        for (int i = 0; i < 32; i++)
            gp[i]->setText("");
    }

    const machine::Registers *regs = machine->registers();
    connect(regs, SIGNAL(pc_update(std::uint32_t)), this, SLOT(pc_changed(std::uint32_t)));
    connect(regs, SIGNAL(gp_update(std::uint8_t,std::uint32_t)), this, SLOT(gp_changed(std::uint8_t,std::uint32_t)));
    connect(regs, SIGNAL(hi_lo_update(bool,std::uint32_t)), this, SLOT(hi_lo_changed(bool,std::uint32_t)));

    // Load values
    labelVal(pc, regs->read_pc());
    labelVal(hi, regs->read_hi_lo(true));
    labelVal(lo, regs->read_hi_lo(false));
    for (int i = 0; i < 32; i++)
        labelVal(gp[i], regs->read_gp(i));
}

void RegistersDock::pc_changed(std::uint32_t val) {
    labelVal(pc, val);
}

void RegistersDock::gp_changed(std::uint8_t i, std::uint32_t val) {
    SANITY_ASSERT(i < 32, QString("RegistersDock received signal with invalid gp register: ") + QString::number(i));
    labelVal(gp[i], val);
}

void RegistersDock::hi_lo_changed(bool hi, std::uint32_t val) {
    if (hi)
        labelVal(this->hi, val);
    else
        labelVal(lo, val);
}

void RegistersDock::labelVal(QLabel *label, std::uint32_t value) {
    QString t = QString("0x") + QString::number(value, 16);
    label->setText(t);
}