-
Notifications
You must be signed in to change notification settings - Fork 0
/
line.cpp
129 lines (99 loc) · 2.16 KB
/
line.cpp
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
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "Machine.h"
#include "dp_register_set.h"
#include "common.h"
#include "Expression.h"
namespace {
#include "gen-attr-table.h"
}
namespace {
unsigned classify(OpCode op, bool longM, bool longX, unsigned &bytes) {
AddressMode mode = op.addressMode();
switch (mode)
{
// lda [%t0] lda [%t0],y
case zp_indirect_long:
case zp_indirect_long_y:
bytes = 3;
return reg_read; // reg_read_indirect?
// lda (%t0)
case zp_indirect:
case zp_indirect_y:
bytes = 2;
return reg_read;
default:
break;
}
switch (op.mnemonic()) {
case ASL:
case DEC:
case INC:
case LSR:
case ROL:
case ROR:
case TRB:
case TSB:
bytes = longM ? 2 : 1;
return reg_rw;
case ADC:
case AND:
case BIT:
case CMP:
case EOR:
case LDA:
case ORA:
case SBC:
bytes = longM ? 2 : 1;
return reg_read;
case CPX:
case CPY:
case LDX:
case LDY:
bytes = longX ? 2 : 1;
return reg_read;
case PEI: // may be caught above by zp_indirect.
bytes = 2;
return reg_read;
// write.
case STA:
case STZ:
bytes = longM ? 2 : 1;
return reg_write;
case STX:
case STY:
bytes = longX ? 2 : 1;
return reg_write;
default:
return reg_none;
}
}
}
register_set BasicLine::read_registers() const {
if (opcode) return read_table[opcode.opcode()];
if (directive == SMART_BRANCH) return branch.read_registers();
return register_set();
}
register_set BasicLine::write_registers() const {
if (opcode) return write_table[opcode.opcode()];
if (directive == SMART_BRANCH) return branch.write_registers();
return register_set();
}
void BasicLine::calc_registers() {
// update reg, reg_count, and reg_status.
reg_status = reg_none;
reg_count = 0;
reg = dp_register();
if (!opcode) {
return;
}
const auto &e = operands[0];
// in the future, may want to track %p variables?
if (e && e->is_register() && e->is_register(reg)) {
unsigned bytes;
reg_status = classify(opcode, longM, longX, bytes);
unsigned a = reg.number & ~0x01;
unsigned b = reg.number + bytes + 1; // +1 to round up for division below.
reg_count = (b - a) >> 1;
reg.number &= ~0x01;
return;
}
}