diff options
author | Kyle Gunger <kgunger12@gmail.com> | 2024-02-14 16:19:36 -0500 |
---|---|---|
committer | Kyle Gunger <kgunger12@gmail.com> | 2024-02-14 16:19:36 -0500 |
commit | f6c62751af043ccae25571bdc9add21c3665d28e (patch) | |
tree | 161b5df9383151c82e99d4adf8d42eefc4f5f8d5 /compiler.c | |
parent | 34d333e387216b38ed00b23ee9560426ac66534a (diff) |
mul and div
Diffstat (limited to 'compiler.c')
-rw-r--r-- | compiler.c | 141 |
1 files changed, 141 insertions, 0 deletions
@@ -1574,6 +1574,77 @@ void var_op_div(CompData *out, Variable *base, Variable *div) { // zero out rdx before divide vect_push_string(&out->text, "\txor rdx, rdx ; Clear rdx for divide\n"); + + char *div_by; + if (base->type->name[0] == 'i') { + // mov into rax + switch(_var_size(base)) { + case 4: + vect_push_string(&out->text, "\tmovsxd rax, "); + break; + case 8: + vect_push_string(&out->text, "\tmov rax, "); + break; + default: + vect_push_string(&out->text, "\tmovsx rax, "); + break; + } + vect_push_free_string(&out->text, _var_get_store(out, base)); + vect_push_string(&out->text, "; initial mov\n\n"); + + // Calculate div_by + if(_var_size(base) > _var_size(div) && div->location == LOC_LITL) { + vect_push_string(&out->text, "\tmov rcx, "); + vect_push_free_string(&out->text, int_to_str(div->offset)); + div_by = _op_get_register(3, _var_size(base)); + + } else { + div_by = _var_get_from(out, base, div); + } + + // Do div + vect_push_string(&out->text, "\tidiv "); + vect_push_free_string(&out->text, div_by); + vect_push_string(&out->text, "; div\n"); + + } else { + // mov into rax + switch(_var_size(base)) { + case 4: + vect_push_string(&out->text, "\tmov eax, "); + break; + case 8: + vect_push_string(&out->text, "\tmov rax, "); + break; + default: + vect_push_string(&out->text, "\tmovzx rax, "); + } + vect_push_free_string(&out->text, _var_get_store(out, base)); + vect_push_string(&out->text, "; initial mov\n\n"); + + // Calculate div by + if(_var_size(base) > _var_size(div) && div->location == LOC_LITL) { + vect_push_string(&out->text, "\tmov rcx, "); + vect_push_free_string(&out->text, int_to_str(div->offset)); + div_by = _op_get_register(3, _var_size(base)); + + } else { + div_by = _var_get_from(out, base, div); + } + + // Do div + vect_push_string(&out->text, "\tdiv "); + vect_push_free_string(&out->text, div_by); + vect_push_string(&out->text, "; div\n"); + } + + // Mov back to base + vect_push_string(&out->text, "\tmov "); + vect_push_free_string(&out->text, _var_get_store(out, base)); + vect_push_string(&out->text, ", "); + vect_push_free_string(&out->text, _op_get_register(1, _var_size(base))); + vect_push_string(&out->text, "; final mov for div\n\n"); + } // Divides "base" by "mod" and sets "base" to the remainder @@ -1586,6 +1657,76 @@ void var_op_mod(CompData *out, Variable *base, Variable *mod) { // zero out rdx before divide vect_push_string(&out->text, "\txor rdx, rdx ; Clear rdx for divide\n"); + + char *div_by; + if (base->type->name[0] == 'i') { + // mov into rax + switch(_var_size(base)) { + case 4: + vect_push_string(&out->text, "\tmovsxd rax, "); + break; + case 8: + vect_push_string(&out->text, "\tmov rax, "); + break; + default: + vect_push_string(&out->text, "\tmovsx rax, "); + break; + } + vect_push_free_string(&out->text, _var_get_store(out, base)); + vect_push_string(&out->text, "; initial mov\n\n"); + + // Calculate div_by + if(_var_size(base) > _var_size(mod) && mod->location == LOC_LITL) { + vect_push_string(&out->text, "\tmov rcx, "); + vect_push_free_string(&out->text, int_to_str(mod->offset)); + div_by = _op_get_register(3, _var_size(base)); + + } else { + div_by = _var_get_from(out, base, mod); + } + + // Do div + vect_push_string(&out->text, "\tidiv "); + vect_push_free_string(&out->text, div_by); + vect_push_string(&out->text, "; div\n"); + + } else { + // mov into rax + switch(_var_size(base)) { + case 4: + vect_push_string(&out->text, "\tmov eax, "); + break; + case 8: + vect_push_string(&out->text, "\tmov rax, "); + break; + default: + vect_push_string(&out->text, "\tmovzx rax, "); + } + vect_push_free_string(&out->text, _var_get_store(out, base)); + vect_push_string(&out->text, "; initial mov\n\n"); + + // Calculate div by + if(_var_size(base) > _var_size(mod) && mod->location == LOC_LITL) { + vect_push_string(&out->text, "\tmov rcx, "); + vect_push_free_string(&out->text, int_to_str(mod->offset)); + div_by = _op_get_register(3, _var_size(base)); + + } else { + div_by = _var_get_from(out, base, mod); + } + + // Do div + vect_push_string(&out->text, "\tdiv "); + vect_push_free_string(&out->text, div_by); + vect_push_string(&out->text, "; div\n"); + } + + // Mov back to base + vect_push_string(&out->text, "\tmov "); + vect_push_free_string(&out->text, _var_get_store(out, base)); + vect_push_string(&out->text, ", "); + vect_push_free_string(&out->text, _op_get_register(4, _var_size(base))); + vect_push_string(&out->text, "; final mov for mod\n\n"); } |