@@ -237,6 +237,14 @@ namespace basecode::vm {
237
237
bytes (str_bytes);
238
238
}
239
239
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
+
240
248
void instruction_block::bytes (const std::vector<uint8_t >& values) {
241
249
data_definition_t def {
242
250
.size = op_sizes::byte,
@@ -531,6 +539,36 @@ namespace basecode::vm {
531
539
make_swap_instruction (dest_reg.size , dest_reg, src_reg);
532
540
}
533
541
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
+
534
572
void instruction_block::push_locals (vm::assembler& assembler) {
535
573
for (const auto & kvp : _locals) {
536
574
auto local = _entries[kvp.second ].data <local_t >();
@@ -639,6 +677,36 @@ namespace basecode::vm {
639
677
}
640
678
641
679
// 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
+
642
710
void instruction_block::pop_locals (vm::assembler& assembler) {
643
711
for (auto it = _locals.rbegin (); it != _locals.rend (); ++it) {
644
712
auto local = _entries[(*it).second ].data <local_t >();
@@ -1058,7 +1126,12 @@ namespace basecode::vm {
1058
1126
}
1059
1127
1060
1128
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
+ }
1062
1135
}
1063
1136
1064
1137
void instruction_block::label (vm::label* value) {
@@ -1072,11 +1145,12 @@ namespace basecode::vm {
1072
1145
}
1073
1146
1074
1147
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
+ }
1080
1154
}
1081
1155
1082
1156
bool instruction_block::is_current_instruction (op_codes code) {
@@ -1093,15 +1167,30 @@ namespace basecode::vm {
1093
1167
}
1094
1168
1095
1169
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
+ }
1097
1176
}
1098
1177
1099
1178
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
+ }
1101
1185
}
1102
1186
1103
1187
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
+ }
1105
1194
}
1106
1195
1107
1196
bool instruction_block::has_local (const std::string& name) const {
@@ -1113,20 +1202,42 @@ namespace basecode::vm {
1113
1202
}
1114
1203
1115
1204
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
+ }
1117
1211
}
1118
1212
1119
1213
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
+ }
1121
1220
}
1122
1221
1123
1222
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
+ }
1126
1232
}
1127
1233
1128
1234
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
+ }
1130
1241
}
1131
1242
1132
1243
const vm::local_t * instruction_block::local (const std::string& name) const {
@@ -1137,7 +1248,14 @@ namespace basecode::vm {
1137
1248
}
1138
1249
1139
1250
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
+ }
1141
1259
}
1142
1260
1143
1261
};
0 commit comments