/## Copyright 2021-2022 Kyle Gunger This file is licensed under the CDDL 1.0 (the License) and may only be used in accordance with the License. You should have received a copy of the License with this software/source code. If you did not, a copy can be found at the following URL: https://opensource.org/licenses/CDDL-1.0 THIS SOFTWARE/SOURCE CODE IS PROVIDED "AS IS" WITH NO WARRANTY, GUARANTEE, OR CLAIM OF FITNESS FOR ANY PURPOSE EXPRESS OR IMPLIED #/ /; construct_statement({}charp base, {}{}charp args) [{}charp] /; loop (int i = 0; i < len args) [i++] ;add_strings(~base, ~(args{i})) /; if (i < len args - 1) ;base.append(',') ;base.append(' ') ;/ ;/ ;base.append('\n') ;return base ;/ /; literal_num ({}charp num) [{}charp] ;{}charp out = "$" ;add_strings(~out, ~num) ;return out ;/ /; add_asm ({}charp from, to) [{}charp] ;return construct_statement("\tadd ", {from, to}) ;/ /; sub_asm({}charp from, to) [{}charp] ;return construct_statement("\tsub ", {from, to}) ;/ /; push_asm ({}charp reg) [{}charp] ;return construct_statement("\tpush ", {reg}) ;/ /; pop_asm ({}charp reg) [{}charp] ;return construct_statement("\tpop ", {reg}) ;/ /; cmp_asm ({}charp a, b) [{}charp] ;return construct_statement("\tcmp ", {a, b}) ;/ /; jmp_asm ({}charp pos) [{}charp] ;return construct_statement("\tjmp ", {pos}) ;/ /; cjmp_asm ({}charp suffix, pos) [{}charp] ;{}charp p = "\tj" ;add_strings(~p, ~suffix) ;p.append(' ') ;return construct_statement(p, {pos}) ;/ /; mem_offset ({}charp pos, offset, scale) [{}charp] ;{}charp tmp = construct_statement("(", {pos, offset, scale}) ;tmp{len tmp - 1} = ')' ;return tmp ;/ /; header_guard (~{}charp csec) [{}charp] ;{}charp out = "", tmp = "" ;tmp = push_asm("%r8") ;add_strings(~out, ~tmp) ;tmp = push_asm("%r9") ;add_strings(~out, ~tmp) ;tmp = push_asm("%r10") ;add_strings(~out, ~tmp) ;tmp = push_asm("%r11") ;add_strings(~out, ~tmp) ;tmp = push_asm("%r12") ;add_strings(~out, ~tmp) ;tmp = push_asm("%r13") ;add_strings(~out, ~tmp) ;tmp = push_asm("%r14") ;add_strings(~out, ~tmp) ;tmp = push_asm("%r15") ;add_strings(~out, ~tmp) ;add_strings(csec, ~out) ;/ /; tail_guard (~{}charp csec) [{}charp] ;{}charp out = "", tmp = "" ;tmp = pop_asm("%r15") ;add_strings(~out, ~tmp) ;tmp = pop_asm("%r14") ;add_strings(~out, ~tmp) ;tmp = pop_asm("%r13") ;add_strings(~out, ~tmp) ;tmp = pop_asm("%r12") ;add_strings(~out, ~tmp) ;tmp = pop_asm("%r11") ;add_strings(~out, ~tmp) ;tmp = pop_asm("%r10") ;add_strings(~out, ~tmp) ;tmp = pop_asm("%r9") ;add_strings(~out, ~tmp) ;tmp = pop_asm("%r8") ;add_strings(~out, ~tmp) ;add_strings(csec, ~out) ;/ /; is_common_reg ({}charp n) [bool] ;return string_equate(n, "ax") || string_equate(n, "bx") || string_equate(n, "cx") || string_equate(n, "dx") || string_equate(n, "sp") || string_equate(n, "bp") || string_equate(n, "si") || string_equate(n, "di") || string_equate(n, "8") || string_equate(n, "9") || string_equate(n, "10") || string_equate(n, "11") || string_equate(n, "12") || string_equate(n, "13") || string_equate(n, "14") || string_equate(n, "15") ;/ /# Accepted common names: # - ax # - bx # - cx # - dx # - sp # - bp # - si # - di # - 8-15 #/ /; get_reg (uint size, {}charp common) [{}charp] ;{}charp out = "%" /; if (string_equate(common, "ax") || string_equate(common, "bx") || string_equate(common, "cx") || string_equate(common, "dx")) /; if (size == 1) ;common{1} = 'l' ;; else if (size == 4) ;out.append('e') ;; else if (size == 8) ;out.append('r') ;/ ;add_strings(~out, ~common) ;; else if (string_equate(common, "sp") || string_equate(common, "bp") || string_equate(common, "si") || string_equate(common, "di")) /; if (size == 1) ;common.append('l') ;; else if (size == 4) ;out.append('e') ;; else if (size == 8) ;out.append('r') ;/ ;add_strings(~out, ~common) ;; else ;{}charp out = "r" ;add_strings(~out, ~common) /; if (size == 1) ;out.append('b') ;; else if (size == 2) ;out.append('w') ;; else if (size == 4) ;out.append('d') ;/ ;return out ;/ ;return out ;/ /; make_label ({}charp func_name, func_place, ~{}charp csec) ;func_name.append("_") ;add_strings(~func_name, ~func_place) ;func_name.append(':') ;func_name.append('\n') ;add_strings(csec, ~func_name) ;/