summaryrefslogtreecommitdiff
path: root/compiler.c
diff options
context:
space:
mode:
Diffstat (limited to 'compiler.c')
-rw-r--r--compiler.c82
1 files changed, 77 insertions, 5 deletions
diff --git a/compiler.c b/compiler.c
index 715a4f8..73a881c 100644
--- a/compiler.c
+++ b/compiler.c
@@ -910,6 +910,7 @@ void var_op_pure_set(CompData *out, Variable *store, Variable *from) {
}
}
+
// Specific setting rules for pointers
void _var_op_set_ptr(CompData *out, Variable *store, Variable *from) {
// Pointer coercion should always work
@@ -989,6 +990,76 @@ void _var_op_set_ptr(CompData *out, Variable *store, Variable *from) {
return;
}
+// Common func to move one variable to another in the case of two
+// inbuilts
+void _var_op_set_inbuilt(CompData *out, Variable *store, Variable *from) {
+ char *mov_from;
+ char *mov_to;
+
+ // Cases for source/dest:
+ // register
+ // stack
+ // data
+ // reference
+
+ // Cases for types
+ // uint - range from 1 to 8 bytes - zx expansion
+ // int - range from 1 to 8 bytes - sx expansion
+ // bool - always 1 byte
+ // float - not impl
+ // void - should only be used to represent ptrs, so we should not see it here.
+
+ // In case of references
+ if (_var_ptr_type(store) == PTYPE_REF){
+ vect_push_string(&out->text, "\tmov rdi, ");
+ vect_push_free_string(&out->text, _op_get_location(store));
+ vect_push_string(&out->text, " ; pre-deref for inbuilt mov\n");
+
+ for(size_t i = store->ptr_chain.count - 1; i > 0; i--){
+ int *cur = vect_get(&store->ptr_chain, i);
+ if (cur == PTYPE_REF) {
+ vect_push_string(&out->text, "\tmov rsi, [rsi] ; deref for mov\n");
+ } else
+ break; // Should not happen
+ }
+
+ mov_to = _gen_address(PREFIXES[_var_size(store) - 1], "rdi", "", 0, 0);
+ } else if (store->location == 0) {
+ mov_to = _gen_address(PREFIXES[_var_size(store) - 1], store->name, "", 0, 0);
+ } else if (store->location < 0) {
+ mov_to = _gen_address(PREFIXES[_var_size(store) - 1], "rsp", "", 0, -(store->location + 1));
+ } else {
+ mov_to = _op_get_location(store);
+ }
+
+ // TODO: Get mov_from for this func
+
+
+ // Match sign of data if required.
+ if (_var_size(from) < _var_size(store)) {
+ if(from->type->name[0] == 'i' && store->type->name[0] == 'i') {
+ if (_var_size(from) < 4)
+ vect_push_string(&out->text, "\tmovsx rsi, ");
+ else
+ vect_push_string(&out->text, "\tmovsxd rsi, ");
+ } else {
+ if(_var_size(from) < 4)
+ vect_push_string(&out->text, "\tmovzx rsi, ");
+ else
+ vect_push_string(&out->text, "\tmovzxd rsi, ");
+ }
+ vect_push_free_string(&out->text, mov_from);
+ vect_push_string(&out->text, " ; Sign extension for mov\n");
+ mov_from = _op_get_register(5, _var_size(store));
+ }
+
+ vect_push_string(&out->text, "\tmov ");
+ vect_push_free_string(&out->text, mov_to);
+ vect_push_string(&out->text, ", ");
+ vect_push_free_string(&out->text, mov_from);
+ vect_push_string(&out->text, " ; Finish mov_inbuilt\n\n");
+}
+
// Tries it's best to coerce the data from "from" into a format
// which will be accepted by "store", following refences in the process.
// This is similar to a normal move operation.
@@ -1003,12 +1074,9 @@ void var_op_set(CompData *out, Variable *store, Variable *from) {
return;
}
- char *mov_from;
- char *mov_to;
-
if(is_inbuilt(from->type->name)) {
// Inbuilt types like int, uint, void, etc.
-
+ _var_op_set_inbuilt(out, store, from);
} else {
// Two structs, we should only copy as much data as we can from one to another,
// and so will defer to the storage variable for how much to transfer
@@ -1127,7 +1195,11 @@ void var_op_sub(CompData *out, Variable *base, Variable *sub) {
// Multiplies "base" by "mul" and sets "base" to the result.
void var_op_mul(CompData *out, Variable *base, Variable *mul) {
-
+ if(base->type->name[0] == 'i') {
+ // Integer multiplication
+ } else {
+ vect_push_string(&out->text, "\tmul ");
+ }
}
// Divides "base" by "div" and sets "base" to the result