flat assembler
Message board for the users of flat assembler.
Index
> Macroinstructions > Linux 64 bit call macro |
Author |
|
ProphetOfDoom 12 Apr 2012, 06:48
Fixed several catastrophic bugs related to functions with > 6 arguments. Also optimised away some useless stack prodding. Pls re-copy/paste if there's anybody out there, lol...
Code: macro unix64call proc,[arg] { common local G_ARG_INDEX local F_ARG_INDEX local ARG_IS_FLOAT local ARG_IS_STRING local G_ARG0_STORED local G_ARG1_STORED local G_ARG2_STORED local G_ARG3_STORED local G_ARG4_STORED local F_ARG0_STORED local F_ARG1_STORED local F_ARG2_STORED local F_ARG3_STORED local F_ARG4_STORED local F_ARG5_STORED local F_ARG6_STORED local NUM_XMM_ARGS local NUM_FLOAT_ARGS local NUM_GENERAL_ARGS local NUM_STACK_ARGS local NUM_ARGS_PUSHED G_ARG_INDEX = 0 F_ARG_INDEX = 0 ARG_IS_FLOAT = 0 ARG_IS_STRING = 0 G_ARG0_STORED = 0 G_ARG1_STORED = 0 G_ARG2_STORED = 0 G_ARG3_STORED = 0 G_ARG4_STORED = 0 F_ARG0_STORED = 0 F_ARG1_STORED = 0 F_ARG2_STORED = 0 F_ARG3_STORED = 0 F_ARG4_STORED = 0 F_ARG5_STORED = 0 F_ARG6_STORED = 0 NUM_XMM_ARGS = 0 NUM_FLOAT_ARGS = 0 NUM_GENERAL_ARGS = 0 NUM_STACK_ARGS = 0 NUM_ARGS_PUSHED = 0 forward if G_ARG_INDEX > 5 | F_ARG_INDEX > 7 NUM_STACK_ARGS = NUM_STACK_ARGS + 1 end if match =float mem_float, arg \{ ARG_IS_FLOAT = 1 \} if arg eqtype 1.0 | arg in <xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7> | ARG_IS_FLOAT F_ARG_INDEX = F_ARG_INDEX + 1 NUM_FLOAT_ARGS = NUM_FLOAT_ARGS + 1 else if ~(arg eq ) G_ARG_INDEX = G_ARG_INDEX + 1 NUM_GENERAL_ARGS = NUM_GENERAL_ARGS + 1 end if ARG_IS_FLOAT = 0 common if NUM_GENERAL_ARGS + NUM_FLOAT_ARGS if ~((NUM_STACK_ARGS = 0) | ((NUM_STACK_ARGS mod 2) = 0)) sub rsp, 8 else sub rsp, 16 end if mov [rsp], rax G_ARG_INDEX = 0 F_ARG_INDEX = 0 end if common F_ARG_INDEX = NUM_FLOAT_ARGS G_ARG_INDEX = NUM_GENERAL_ARGS reverse if NUM_GENERAL_ARGS + NUM_FLOAT_ARGS match =float mem_float, arg \{ ARG_IS_FLOAT = 1 \} contains_strings ARG_IS_STRING, arg if arg eqtype 1.0 | arg in <xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7> | ARG_IS_FLOAT F_ARG_INDEX = F_ARG_INDEX - 1 else G_ARG_INDEX = G_ARG_INDEX - 1 end if if arg in <xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7> if F_ARG_INDEX > 7 sub rsp, 8 movq [rsp], arg NUM_ARGS_PUSHED = NUM_ARGS_PUSHED + 1 end if else if arg eqtype 1.0 if F_ARG_INDEX > 7 mov rax, arg push rax NUM_ARGS_PUSHED = NUM_ARGS_PUSHED + 1 end if else if ARG_IS_FLOAT if F_ARG_INDEX > 7 match =float mem_float, arg \{ push mem_float NUM_ARGS_PUSHED = NUM_ARGS_PUSHED + 1 \} end if else if ARG_IS_STRING if G_ARG_INDEX > 5 call @f db arg, 0 @@: NUM_ARGS_PUSHED = NUM_ARGS_PUSHED + 1 end if else if G_ARG_INDEX > 5 if arg eq rax push qword [rsp + 8 * NUM_ARGS_PUSHED] else push arg end if NUM_ARGS_PUSHED = NUM_ARGS_PUSHED + 1 end if ARG_IS_FLOAT = 0 ARG_IS_STRING = 0 end if common F_ARG_INDEX = 0 G_ARG_INDEX = 0 forward if NUM_GENERAL_ARGS + NUM_FLOAT_ARGS if G_ARG_INDEX < 6 & arg eq rax push rax else if G_ARG_INDEX = 0 & arg in <rsi,rdx,rcx,r8,r9> push arg G_ARG0_STORED = 1 else if G_ARG_INDEX = 1 & arg in <rdx,rcx,r8,r9> push arg G_ARG1_STORED = 1 else if G_ARG_INDEX = 2 & arg in <rcx,r8,r9> push arg G_ARG2_STORED = 1 else if G_ARG_INDEX = 3 & arg in <r8,r9> push arg G_ARG3_STORED = 1 else if G_ARG_INDEX = 4 & arg in <r9> push arg G_ARG4_STORED = 1 else if F_ARG_INDEX = 0 & arg in <xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7> movq rax, arg push rax F_ARG0_STORED = 1 else if F_ARG_INDEX = 1 & arg in <xmm2,xmm3,xmm4,xmm5,xmm6,xmm7> movq rax, arg push rax F_ARG1_STORED = 1 else if F_ARG_INDEX = 2 & arg in <xmm3,xmm4,xmm5,xmm6,xmm7> movq rax, arg push rax F_ARG2_STORED = 1 else if F_ARG_INDEX = 3 & arg in <xmm4,xmm5,xmm6,xmm7> movq rax, arg push rax F_ARG3_STORED = 1 else if F_ARG_INDEX = 4 & arg in <xmm5,xmm6,xmm7> movq rax, arg push rax F_ARG4_STORED = 1 else if F_ARG_INDEX = 5 & arg in <xmm6,xmm7> movq rax, arg push rax F_ARG5_STORED = 1 else if F_ARG_INDEX = 6 & arg in <xmm7> movq rax, arg push rax F_ARG6_STORED = 1 end if match =float mem_float, arg \{ ARG_IS_FLOAT = 1 \} if arg eqtype 1.0 | arg in <xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7> | ARG_IS_FLOAT F_ARG_INDEX = F_ARG_INDEX + 1 else G_ARG_INDEX = G_ARG_INDEX + 1 end if ARG_IS_FLOAT = 0 end if common F_ARG_INDEX = NUM_FLOAT_ARGS G_ARG_INDEX = NUM_GENERAL_ARGS reverse if NUM_GENERAL_ARGS + NUM_FLOAT_ARGS match =float mem_float, arg \{ ARG_IS_FLOAT = 1 \} contains_strings ARG_IS_STRING, arg if arg eqtype 1.0 | arg in <xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7> | ARG_IS_FLOAT if NUM_XMM_ARGS < 8 NUM_XMM_ARGS = NUM_XMM_ARGS + 1 end if F_ARG_INDEX = F_ARG_INDEX - 1 else G_ARG_INDEX = G_ARG_INDEX - 1 end if if arg in <xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7> if F_ARG_INDEX = 7 & ~(arg eq xmm7) movq xmm7, arg else if F_ARG_INDEX = 6 & F_ARG6_STORED pop rax movq xmm6, rax else if F_ARG_INDEX = 6 & ~(arg eq xmm6) movq xmm6, arg else if F_ARG_INDEX = 5 & F_ARG5_STORED pop rax movq xmm5, rax else if F_ARG_INDEX = 5 & ~(arg eq xmm5) movq xmm5, arg else if F_ARG_INDEX = 4 & F_ARG4_STORED pop rax movq xmm4, rax else if F_ARG_INDEX = 4 & ~(arg eq xmm4) movq xmm4, arg else if F_ARG_INDEX = 3 & F_ARG3_STORED pop rax movq xmm3, rax else if F_ARG_INDEX = 3 & ~(arg eq xmm3) movq xmm3, arg else if F_ARG_INDEX = 2 & F_ARG2_STORED pop rax movq xmm2, rax else if F_ARG_INDEX = 2 & ~(arg eq xmm2) movq xmm2, arg else if F_ARG_INDEX = 1 & F_ARG1_STORED pop rax movq xmm1, rax else if F_ARG_INDEX = 1 & ~(arg eq xmm1) movq xmm1, arg else if F_ARG_INDEX = 0 & F_ARG0_STORED pop rax movq xmm0, rax else if F_ARG_INDEX = 0 & ~(arg eq xmm0) movq xmm0, arg end if else if arg eqtype 1.0 if F_ARG_INDEX = 7 mov rax, arg movq xmm7, rax else if F_ARG_INDEX = 6 mov rax, arg movq xmm6, rax else if F_ARG_INDEX = 5 mov rax, arg movq xmm5, rax else if F_ARG_INDEX = 4 mov rax, arg movq xmm4, rax else if F_ARG_INDEX = 3 mov rax, arg movq xmm3, rax else if F_ARG_INDEX = 2 mov rax, arg movq xmm2, rax else if F_ARG_INDEX = 1 mov rax, arg movq xmm1, rax else if F_ARG_INDEX = 0 mov rax, arg movq xmm0, rax end if else if ARG_IS_FLOAT match =float mem_float, arg \{ if F_ARG_INDEX = 7 movq xmm7, mem_float else if F_ARG_INDEX = 6 movq xmm6, mem_float else if F_ARG_INDEX = 5 movq xmm5, mem_float else if F_ARG_INDEX = 4 movq xmm4, mem_float else if F_ARG_INDEX = 3 movq xmm3, mem_float else if F_ARG_INDEX = 2 movq xmm2, mem_float else if F_ARG_INDEX = 1 movq xmm1, mem_float else if F_ARG_INDEX = 0 movq xmm0, mem_float end if \} else if ARG_IS_STRING if G_ARG_INDEX < 6 call @f db arg, 0 @@: if G_ARG_INDEX = 5 pop r9 else if G_ARG_INDEX = 4 pop r8 else if G_ARG_INDEX = 3 pop rcx else if G_ARG_INDEX = 2 pop rdx else if G_ARG_INDEX = 1 pop rsi else if G_ARG_INDEX = 0 pop rdi end if end if else if G_ARG_INDEX = 5 & arg eq rax pop r9 else if G_ARG_INDEX = 5 & ~(arg eq r9) mov r9, arg else if G_ARG_INDEX = 4 & (G_ARG4_STORED | arg eq rax) pop r8 else if G_ARG_INDEX = 4 & ~(arg eq r8) mov r8, arg else if G_ARG_INDEX = 3 & (G_ARG3_STORED | arg eq rax) pop rcx else if G_ARG_INDEX = 3 & ~(arg eq rcx) mov rcx, arg else if G_ARG_INDEX = 2 & (G_ARG2_STORED | arg eq rax) pop rdx else if G_ARG_INDEX = 2 & ~(arg eq rdx) mov rdx, arg else if G_ARG_INDEX = 1 & (G_ARG1_STORED | arg eq rax) pop rsi else if G_ARG_INDEX = 1 & ~(arg eq rsi) mov rsi, arg else if G_ARG_INDEX = 0 & (G_ARG0_STORED | arg eq rax) pop rdi else if G_ARG_INDEX = 0 & ~(arg eq rdi) mov rdi, arg end if end if ARG_IS_FLOAT = 0 ARG_IS_STRING = 0 end if common mov rax, NUM_XMM_ARGS call proc if NUM_GENERAL_ARGS + NUM_FLOAT_ARGS if ~((NUM_STACK_ARGS = 0) | ((NUM_STACK_ARGS mod 2) = 0)) add rsp, 8 * (NUM_STACK_ARGS + 1) else add rsp, 8 * (NUM_STACK_ARGS + 2) end if end if } macro contains_strings result, [arg] { result = 0 forward if arg eqtype "fasm" result = 1 end if } |
|||
12 Apr 2012, 06:48 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.