Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e81df71

Browse files
committed
working on temp register usage
1 parent b8ecfb3 commit e81df71

File tree

5 files changed

+302
-49
lines changed

5 files changed

+302
-49
lines changed

basecode/compiler/byte_code_emitter.cpp

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -127,18 +127,21 @@ namespace basecode::compiler {
127127
emit_result_t& result,
128128
uint8_t number) {
129129
const auto& local_ref = result.operands.front();
130-
if (is_temp_local(local_ref)
131-
|| local_ref.type() != vm::instruction_operand_type_t::named_ref) {
130+
if (local_ref.type() != vm::instruction_operand_type_t::named_ref)
132131
return;
133-
}
132+
133+
auto number_class = result.type_result.inferred_type->number_class();
134+
auto temp_name = temp_local_name(number_class, number);
134135

135136
auto named_ref = *local_ref.data<vm::assembler_named_ref_t*>();
136137
if (named_ref->type == vm::assembler_named_ref_type_t::label)
137138
return;
138139

140+
if (temp_name == named_ref->name)
141+
return;
142+
139143
auto is_pointer_type = result.type_result.inferred_type->is_pointer_type();
140144
auto is_composite = result.type_result.inferred_type->is_composite_type();
141-
auto number_class = result.type_result.inferred_type->number_class();
142145
auto size = is_composite ?
143146
vm::op_sizes::qword :
144147
vm::op_size_for_byte_size(result.type_result.inferred_type->size_in_bytes());
@@ -147,18 +150,20 @@ namespace basecode::compiler {
147150
result.operands[1] :
148151
vm::instruction_operand_t();
149152

150-
vm::instruction_operand_t temp(_session.assembler().make_named_ref(
151-
vm::assembler_named_ref_type_t::local,
152-
temp_local_name(number_class, number),
153-
size));
153+
if (!is_temp_local(local_ref) || !offset.is_empty()) {
154+
vm::instruction_operand_t temp(_session.assembler().make_named_ref(
155+
vm::assembler_named_ref_type_t::local,
156+
temp_name,
157+
size));
154158

155-
if (is_composite && !is_pointer_type) {
156-
block->move(temp, local_ref, offset);
157-
} else {
158-
block->load(temp, local_ref, offset);
159-
}
159+
if (is_composite && !is_pointer_type) {
160+
block->move(temp, local_ref, offset);
161+
} else {
162+
block->load(temp, local_ref, offset);
163+
}
160164

161-
result.operands.push_back(temp);
165+
result.operands.push_back(temp);
166+
}
162167
}
163168

164169
bool byte_code_emitter::emit() {
@@ -1389,10 +1394,19 @@ namespace basecode::compiler {
13891394
auto unary_op = dynamic_cast<compiler::unary_operator*>(e);
13901395
auto op_type = unary_op->operator_type();
13911396

1397+
switch (op_type) {
1398+
case operator_type_t::pointer_dereference: {
1399+
block->comment("unary_op: deref", vm::comment_location_t::after_instruction);
1400+
break;
1401+
}
1402+
default:
1403+
break;
1404+
}
1405+
13921406
emit_result_t rhs_emit_result {};
13931407
if (!emit_element(block, unary_op->rhs(), rhs_emit_result))
13941408
return false;
1395-
read(block, rhs_emit_result, 1);
1409+
read(block, rhs_emit_result, 2);
13961410

13971411
auto is_composite_type = rhs_emit_result.type_result.inferred_type->is_composite_type();
13981412
auto size = vm::op_size_for_byte_size(result.type_result.inferred_type->size_in_bytes());
@@ -1404,7 +1418,7 @@ namespace basecode::compiler {
14041418

14051419
vm::instruction_operand_t result_operand(assembler.make_named_ref(
14061420
vm::assembler_named_ref_type_t::local,
1407-
temp_local_name(result.type_result.inferred_type->number_class(), 1),
1421+
temp_local_name(result.type_result.inferred_type->number_class(), 3),
14081422
size));
14091423

14101424
switch (op_type) {
@@ -1435,7 +1449,6 @@ namespace basecode::compiler {
14351449
break;
14361450
}
14371451
case operator_type_t::pointer_dereference: {
1438-
block->comment("unary_op: deref", vm::comment_location_t::after_instruction);
14391452
if (!is_composite_type) {
14401453
block->load(
14411454
result_operand,
@@ -1746,18 +1759,14 @@ namespace basecode::compiler {
17461759
auto unary_op = dynamic_cast<compiler::unary_operator*>(e);
17471760
if (!count_temps(unary_op->rhs(), result))
17481761
return false;
1749-
result.update();
17501762
break;
17511763
}
17521764
case element_type_t::binary_operator: {
17531765
auto bin_op = dynamic_cast<compiler::binary_operator*>(e);
1754-
if (bin_op->operator_type() != operator_type_t::assignment) {
1755-
if (!count_temps(bin_op->lhs(), result))
1756-
return false;
1757-
}
1766+
if (!count_temps(bin_op->lhs(), result))
1767+
return false;
17581768
if (!count_temps(bin_op->rhs(), result))
17591769
return false;
1760-
result.update();
17611770
break;
17621771
}
17631772
case element_type_t::identifier_reference: {
@@ -1790,15 +1799,14 @@ namespace basecode::compiler {
17901799
continue;
17911800
if (!count_temps(expr, result))
17921801
return false;
1802+
result.update();
17931803
}
17941804
return true;
17951805
},
17961806
block);
17971807
if (!success)
17981808
return false;
17991809

1800-
result.update();
1801-
18021810
for (size_t i = 1; i <= result.ints; i++) {
18031811
locals.push_back(temp_local_t{
18041812
fmt::format("itemp{}", i),

basecode/vm/instruction_block.cpp

Lines changed: 133 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,14 @@ namespace basecode::vm {
237237
bytes(str_bytes);
238238
}
239239

240+
ssize_t instruction_block::insertion_point() const {
241+
return _insertion_point != -1 ? _insertion_point : _entries.size();
242+
}
243+
244+
void instruction_block::insertion_point(ssize_t value) {
245+
_insertion_point = value;
246+
}
247+
240248
void instruction_block::bytes(const std::vector<uint8_t>& values) {
241249
data_definition_t def {
242250
.size = op_sizes::byte,
@@ -531,6 +539,36 @@ namespace basecode::vm {
531539
make_swap_instruction(dest_reg.size, dest_reg, src_reg);
532540
}
533541

542+
void instruction_block::pushm(
543+
const register_range_t& first,
544+
const register_range_t& second,
545+
const register_range_t& third,
546+
const register_range_t& fourth) {
547+
instruction_t op;
548+
op.operands_count = 1;
549+
op.op = op_codes::pushm;
550+
op.size = op_sizes::qword;
551+
552+
op.operands[0].type = operand_encoding_t::flags::reg | operand_encoding_t::flags::negative;
553+
554+
if (!second.empty()) {
555+
op.operands[1].type = operand_encoding_t::flags::reg | operand_encoding_t::flags::negative;
556+
op.operands_count++;
557+
}
558+
559+
if (!third.empty()) {
560+
op.operands[2].type = operand_encoding_t::flags::reg | operand_encoding_t::flags::negative;
561+
op.operands_count++;
562+
}
563+
564+
if (!fourth.empty()) {
565+
op.operands[3].type = operand_encoding_t::flags::reg | operand_encoding_t::flags::negative;
566+
op.operands_count++;
567+
}
568+
569+
make_block_entry(op);
570+
}
571+
534572
void instruction_block::push_locals(vm::assembler& assembler) {
535573
for (const auto& kvp : _locals) {
536574
auto local = _entries[kvp.second].data<local_t>();
@@ -639,6 +677,36 @@ namespace basecode::vm {
639677
}
640678

641679
// pop variations
680+
void instruction_block::popm(
681+
const register_range_t& first,
682+
const register_range_t& second,
683+
const register_range_t& third,
684+
const register_range_t& fourth) {
685+
instruction_t op;
686+
op.operands_count = 1;
687+
op.op = op_codes::popm;
688+
op.size = op_sizes::qword;
689+
690+
op.operands[0].type = operand_encoding_t::flags::reg | operand_encoding_t::flags::negative;
691+
692+
if (!second.empty()) {
693+
op.operands[1].type = operand_encoding_t::flags::reg | operand_encoding_t::flags::negative;
694+
op.operands_count++;
695+
}
696+
697+
if (!third.empty()) {
698+
op.operands[2].type = operand_encoding_t::flags::reg | operand_encoding_t::flags::negative;
699+
op.operands_count++;
700+
}
701+
702+
if (!fourth.empty()) {
703+
op.operands[3].type = operand_encoding_t::flags::reg | operand_encoding_t::flags::negative;
704+
op.operands_count++;
705+
}
706+
707+
make_block_entry(op);
708+
}
709+
642710
void instruction_block::pop_locals(vm::assembler& assembler) {
643711
for (auto it = _locals.rbegin(); it != _locals.rend(); ++it) {
644712
auto local = _entries[(*it).second].data<local_t>();
@@ -1058,7 +1126,12 @@ namespace basecode::vm {
10581126
}
10591127

10601128
void instruction_block::blank_line() {
1061-
_entries.push_back(block_entry_t());
1129+
if (_insertion_point != -1) {
1130+
_entries.insert(std::begin(_entries) + _insertion_point, block_entry_t());
1131+
_insertion_point++;
1132+
} else {
1133+
_entries.push_back(block_entry_t());
1134+
}
10621135
}
10631136

10641137
void instruction_block::label(vm::label* value) {
@@ -1072,11 +1145,12 @@ namespace basecode::vm {
10721145
}
10731146

10741147
void instruction_block::make_block_entry(const meta_t& meta) {
1075-
_entries.push_back(block_entry_t(meta));
1076-
}
1077-
1078-
void instruction_block::add_entry(const block_entry_t& entry) {
1079-
_entries.push_back(entry);
1148+
if (_insertion_point != -1) {
1149+
_entries.insert(std::begin(_entries) + _insertion_point, block_entry_t(meta));
1150+
_insertion_point++;
1151+
} else {
1152+
_entries.push_back(block_entry_t(meta));
1153+
}
10801154
}
10811155

10821156
bool instruction_block::is_current_instruction(op_codes code) {
@@ -1093,15 +1167,30 @@ namespace basecode::vm {
10931167
}
10941168

10951169
void instruction_block::make_block_entry(const local_t& local) {
1096-
_entries.push_back(block_entry_t(local));
1170+
if (_insertion_point != -1) {
1171+
_entries.insert(std::begin(_entries) + _insertion_point, block_entry_t(local));
1172+
_insertion_point++;
1173+
} else {
1174+
_entries.push_back(block_entry_t(local));
1175+
}
10971176
}
10981177

10991178
void instruction_block::make_block_entry(const label_t& label) {
1100-
_entries.push_back(block_entry_t(label));
1179+
if (_insertion_point != -1) {
1180+
_entries.insert(std::begin(_entries) + _insertion_point, block_entry_t(label));
1181+
_insertion_point++;
1182+
} else {
1183+
_entries.push_back(block_entry_t(label));
1184+
}
11011185
}
11021186

11031187
void instruction_block::make_block_entry(const align_t& align) {
1104-
_entries.push_back(block_entry_t(align));
1188+
if (_insertion_point != -1) {
1189+
_entries.insert(std::begin(_entries) + _insertion_point, block_entry_t(align));
1190+
_insertion_point++;
1191+
} else {
1192+
_entries.push_back(block_entry_t(align));
1193+
}
11051194
}
11061195

11071196
bool instruction_block::has_local(const std::string& name) const {
@@ -1113,20 +1202,42 @@ namespace basecode::vm {
11131202
}
11141203

11151204
void instruction_block::make_block_entry(const comment_t& comment) {
1116-
_entries.push_back(block_entry_t(comment));
1205+
if (_insertion_point != -1) {
1206+
_entries.insert(std::begin(_entries) + _insertion_point, block_entry_t(comment));
1207+
_insertion_point++;
1208+
} else {
1209+
_entries.push_back(block_entry_t(comment));
1210+
}
11171211
}
11181212

11191213
void instruction_block::make_block_entry(const section_t& section) {
1120-
_entries.push_back(block_entry_t(section));
1214+
if (_insertion_point != -1) {
1215+
_entries.insert(std::begin(_entries) + _insertion_point, block_entry_t(section));
1216+
_insertion_point++;
1217+
} else {
1218+
_entries.push_back(block_entry_t(section));
1219+
}
11211220
}
11221221

11231222
void instruction_block::make_block_entry(const instruction_t& inst) {
1124-
_recent_inst_index = static_cast<int64_t>(_entries.size());
1125-
_entries.push_back(block_entry_t(inst));
1223+
if (_insertion_point != -1) {
1224+
_recent_inst_index = _insertion_point;
1225+
_entries.insert(std::begin(_entries) + _insertion_point, block_entry_t(inst));
1226+
_insertion_point++;
1227+
}
1228+
else {
1229+
_recent_inst_index = static_cast<int64_t>(_entries.size());
1230+
_entries.push_back(block_entry_t(inst));
1231+
}
11261232
}
11271233

11281234
void instruction_block::make_block_entry(const data_definition_t& data) {
1129-
_entries.push_back(block_entry_t(data));
1235+
if (_insertion_point != -1) {
1236+
_entries.insert(std::begin(_entries) + _insertion_point, block_entry_t(data));
1237+
_insertion_point++;
1238+
} else {
1239+
_entries.push_back(block_entry_t(data));
1240+
}
11301241
}
11311242

11321243
const vm::local_t* instruction_block::local(const std::string& name) const {
@@ -1137,7 +1248,14 @@ namespace basecode::vm {
11371248
}
11381249

11391250
void instruction_block::frame_offset(const std::string& name, int64_t offset) {
1140-
_entries.push_back(block_entry_t(frame_offset_t{offset, name}));
1251+
if (_insertion_point != -1) {
1252+
_entries.insert(
1253+
std::begin(_entries) + _insertion_point,
1254+
block_entry_t(frame_offset_t{offset, name}));
1255+
_insertion_point++;
1256+
} else {
1257+
_entries.push_back(block_entry_t(frame_offset_t{offset, name}));
1258+
}
11411259
}
11421260

11431261
};

0 commit comments

Comments
 (0)