-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathformatter.cpp
110 lines (94 loc) · 2.84 KB
/
formatter.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
#include "formatter.h"
#include "assembler.h"
#include "sym_table.h"
#include "entries.h"
#include "reloc_table.h"
#include <iostream>
#include <sstream>
#include <iomanip>
#include <regex>
#include <cstdint>
using namespace std;
bool Formatter::stoint16(std::string& val_string, int16_t& val)
{
int base = 0;
if (regex_match(val_string, regex(REGEX_DEC))) base = 10;
else if (regex_match(val_string, regex(REGEX_HEX))) base = 16;
else {
return false;
}
val = (int16_t)stoi(val_string, nullptr, base);
return true;
}
Formatter::Formatter(Assembler* const a) : my_asm(a), out(a->out) {
out << hex << setfill('0');
}
//mozda ne sme da stvara bocne efekte
template<typename T>
constexpr auto swap16(T& x) { (x) = (((uint16_t)(x) & 0xff00) >> 8) | (((uint16_t)(x) & 0x00ff) << 8); }
const string Formatter::REGEX_DEC = "[1-9]\\d*";
const string Formatter::REGEX_HEX = "(0(x|X))[0-9a-fA-F]+";
/*const string Formatter::REGEX_PARTS[] = {
"((-)?([1-9][0-9]*)|((0(x|X))[0-9a-fA-F]+))", //val
"(([a-zA-Z_])(\\w)*)", //sym
"((((r|R)15)|((r|R)((0(x|X))?[(0-7)|f|F]))|(sp)|(pc)|(psw))(h|l)?)" //reg
};*/
//const int REGEX_PARTS_SIZE = 3;
void Formatter::write(int16_t value, Size w)
{
int16_t mask = w == BYTE ? 0xff : 0xffff;
value &= mask;
out << setw(w) << value;
my_asm->curr_section->location_counter += (w/2);
}
void Formatter::put(int16_t value, Size w)
{
checkRange(value, w);
if (w == WORD) swap16(value);
out << setw(w) << value;
my_asm->curr_section->location_counter += (w / 2);
}
void Formatter::reg_bits(unsigned& op_byte_1, string& reg) {
if (reg != "") {
int h = 0;
char hl = reg.back();
if (hl == 'h') { h = 1; reg.pop_back(); }
else if (hl == 'l') reg.pop_back();
int rind = 0;
if (reg == "r15" || reg == "r0xf" || reg == "psw") rind = 15;
else if (reg == "sp") rind = 6;
else if (reg == "pc") rind = 7;
else {
reg.erase(0, 1); //r
rind = stoi(reg);
}
rind <<= 1;
op_byte_1 |= rind;
//postavljanje bita h/l
if (hl == 'h') h = 1;
//najnizi bit je h/l bit
op_byte_1 |= h;
}
if ((op_byte_1 & ~0xff) != 0) { cout << my_asm->line_counter << "Greska u kodovanju reg_bits" << endl; exit(-1); }
write(op_byte_1, BYTE);
}
void Formatter::val_bits(string& val_string, Size w) {
int16_t val = 0;
if(!stoint16(val_string, val)) {
cout << my_asm->line_counter << "FATAL ERROR" << endl; exit(-1);
}
put(val, w);
}
void Formatter::sym_bits(string& symbol_name, RelocTable::RelocType reloc_type, int16_t add_op2_size) {
int16_t offset = my_asm->sym_table->getCode(symbol_name, reloc_type) + add_op2_size;
put(offset, WORD);
}
void Formatter::checkRange(int val, Size bytes) {
int deg = bytes == Size::BYTE ? 7 : 15;
int minint = 2 << (deg - 1);
int maxint = (2 << (deg - 1)) - 1;
if (val > maxint || val < -minint) {
cout << "[" << my_asm->line_counter << "]" << "Prekoracenje opsega" << endl;
exit(70);
}
}