diff options
Diffstat (limited to 'src/pal/inc/unixasmmacrosamd64.inc')
-rw-r--r-- | src/pal/inc/unixasmmacrosamd64.inc | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/src/pal/inc/unixasmmacrosamd64.inc b/src/pal/inc/unixasmmacrosamd64.inc new file mode 100644 index 0000000000..f221b4406b --- /dev/null +++ b/src/pal/inc/unixasmmacrosamd64.inc @@ -0,0 +1,355 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.macro NESTED_ENTRY Name, Section, Handler + LEAF_ENTRY \Name, \Section + .ifnc \Handler, NoHandler +#if defined(__APPLE__) + .cfi_personality 0x9b, C_FUNC(\Handler) // 0x9b == DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4 +#else + .cfi_personality 0, C_FUNC(\Handler) // 0 == DW_EH_PE_absptr +#endif + .endif +.endm + +.macro NESTED_END Name, Section + LEAF_END \Name, \Section +#if defined(__APPLE__) + .set LOCAL_LABEL(\Name\()_Size), . - C_FUNC(\Name) + .section __LD,__compact_unwind,regular,debug + .quad C_FUNC(\Name) + .long LOCAL_LABEL(\Name\()_Size) + .long 0x04000000 # DWARF + .quad 0 + .quad 0 +#endif +.endm + +.macro PATCH_LABEL Name + .global C_FUNC(\Name) +C_FUNC(\Name): +.endm + +.macro LEAF_ENTRY Name, Section + .global C_FUNC(\Name) +#if defined(__APPLE__) + .text +#else + .type \Name, %function +#endif +C_FUNC(\Name): + .cfi_startproc +.endm + +.macro LEAF_END Name, Section +#if !defined(__APPLE__) + .size \Name, .-\Name +#endif + .cfi_endproc +.endm + +.macro LEAF_END_MARKED Name, Section +C_FUNC(\Name\()_End): + .global C_FUNC(\Name\()_End) + LEAF_END \Name, \Section +.endm + +.macro NOP_3_BYTE + nop dword ptr [rax] +.endm + +.macro NOP_2_BYTE + xchg ax, ax +.endm + +.macro REPRET + .byte 0xf3 + .byte 0xc3 +.endm + +.macro TAILJMP_RAX + .byte 0x48 + .byte 0xFF + .byte 0xE0 +.endm + +.macro PREPARE_EXTERNAL_VAR Name, HelperReg + mov \HelperReg, [rip + C_FUNC(\Name)@GOTPCREL] +.endm + +.macro push_nonvol_reg Register + push \Register + .cfi_adjust_cfa_offset 8 + .cfi_rel_offset \Register, 0 +.endm + +.macro pop_nonvol_reg Register + pop \Register + .cfi_adjust_cfa_offset -8 + .cfi_restore \Register +.endm + +.macro alloc_stack Size +.att_syntax + lea -(\Size)(%rsp), %rsp +.intel_syntax noprefix + .cfi_adjust_cfa_offset \Size +.endm + +.macro free_stack Size +.att_syntax + lea \Size(%rsp), %rsp +.intel_syntax noprefix + .cfi_adjust_cfa_offset -\Size +.endm + +.macro set_cfa_register Reg, Offset + .cfi_def_cfa_register \Reg + .cfi_def_cfa_offset \Offset +.endm + +.macro save_reg_postrsp Reg, Offset + __Offset = \Offset + mov qword ptr [rsp + __Offset], \Reg + .cfi_rel_offset \Reg, __Offset +.endm + +.macro restore_reg Reg, Offset + __Offset = \Offset + mov \Reg, [rsp + __Offset] + .cfi_restore \Reg +.endm + +.macro save_xmm128_postrsp Reg, Offset + __Offset = \Offset + movdqa xmmword ptr [rsp + __Offset], \Reg + // NOTE: We cannot use ".cfi_rel_offset \Reg, __Offset" here, + // the xmm registers are not supported by the libunwind +.endm + +.macro restore_xmm128 Reg, ofs + __Offset = \ofs + movdqa \Reg, xmmword ptr [rsp + __Offset] + // NOTE: We cannot use ".cfi_restore \Reg" here, + // the xmm registers are not supported by the libunwind + +.endm + +.macro PUSH_CALLEE_SAVED_REGISTERS + + push_register rbp + push_register rbx + push_register r15 + push_register r14 + push_register r13 + push_register r12 + +.endm + +.macro POP_CALLEE_SAVED_REGISTERS + + pop_nonvol_reg r12 + pop_nonvol_reg r13 + pop_nonvol_reg r14 + pop_nonvol_reg r15 + pop_nonvol_reg rbx + pop_nonvol_reg rbp + +.endm + +.macro push_register Reg + push \Reg + .cfi_adjust_cfa_offset 8 +.endm + +.macro push_eflags + pushfq + .cfi_adjust_cfa_offset 8 +.endm + +.macro push_argument_register Reg + push_register \Reg +.endm + +.macro PUSH_ARGUMENT_REGISTERS + + push_argument_register r9 + push_argument_register r8 + push_argument_register rcx + push_argument_register rdx + push_argument_register rsi + push_argument_register rdi + +.endm + +.macro pop_register Reg + pop \Reg + .cfi_adjust_cfa_offset -8 +.endm + +.macro pop_eflags + popfq + .cfi_adjust_cfa_offset -8 +.endm + +.macro pop_argument_register Reg + pop_register \Reg +.endm + +.macro POP_ARGUMENT_REGISTERS + + pop_argument_register rdi + pop_argument_register rsi + pop_argument_register rdx + pop_argument_register rcx + pop_argument_register r8 + pop_argument_register r9 + +.endm + +.macro SAVE_FLOAT_ARGUMENT_REGISTERS ofs + + save_xmm128_postrsp xmm0, \ofs + save_xmm128_postrsp xmm1, \ofs + 0x10 + save_xmm128_postrsp xmm2, \ofs + 0x20 + save_xmm128_postrsp xmm3, \ofs + 0x30 + save_xmm128_postrsp xmm4, \ofs + 0x40 + save_xmm128_postrsp xmm5, \ofs + 0x50 + save_xmm128_postrsp xmm6, \ofs + 0x60 + save_xmm128_postrsp xmm7, \ofs + 0x70 + +.endm + +.macro RESTORE_FLOAT_ARGUMENT_REGISTERS ofs + + restore_xmm128 xmm0, \ofs + restore_xmm128 xmm1, \ofs + 0x10 + restore_xmm128 xmm2, \ofs + 0x20 + restore_xmm128 xmm3, \ofs + 0x30 + restore_xmm128 xmm4, \ofs + 0x40 + restore_xmm128 xmm5, \ofs + 0x50 + restore_xmm128 xmm6, \ofs + 0x60 + restore_xmm128 xmm7, \ofs + 0x70 + +.endm + +// Stack layout: +// +// (stack parameters) +// ... +// return address +// CalleeSavedRegisters::rbp +// CalleeSavedRegisters::rbx +// CalleeSavedRegisters::r15 +// CalleeSavedRegisters::r14 +// CalleeSavedRegisters::r13 +// CalleeSavedRegisters::r12 +// ArgumentRegisters::r9 +// ArgumentRegisters::r8 +// ArgumentRegisters::rcx +// ArgumentRegisters::rdx +// ArgumentRegisters::rsi +// ArgumentRegisters::rdi <- __PWTB_StackAlloc, __PWTB_TransitionBlock +// padding to align xmm save area +// xmm7 +// xmm6 +// xmm5 +// xmm4 +// xmm3 +// xmm2 +// xmm1 +// xmm0 <- __PWTB_FloatArgumentRegisters +// extra locals + padding to qword align +.macro PROLOG_WITH_TRANSITION_BLOCK extraLocals = 0, stackAllocOnEntry = 0, stackAllocSpill1, stackAllocSpill2, stackAllocSpill3 + + set_cfa_register rsp, 8 + + __PWTB_FloatArgumentRegisters = \extraLocals + + .if ((__PWTB_FloatArgumentRegisters % 16) != 0) + __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8 + .endif + + __PWTB_StackAlloc = __PWTB_FloatArgumentRegisters + 8 * 16 + 8 // 8 floating point registers + __PWTB_TransitionBlock = __PWTB_StackAlloc + + .if \stackAllocOnEntry >= 4*8 + .error "Max supported stackAllocOnEntry is 3*8" + .endif + + .if \stackAllocOnEntry > 0 + .cfi_adjust_cfa_offset \stackAllocOnEntry + .endif + + // PUSH_CALLEE_SAVED_REGISTERS expanded here + + .if \stackAllocOnEntry < 8 + push_nonvol_reg rbp + mov rbp, rsp + .endif + + .if \stackAllocOnEntry < 2*8 + push_nonvol_reg rbx + .endif + + .if \stackAllocOnEntry < 3*8 + push_nonvol_reg r15 + .endif + + push_nonvol_reg r14 + push_nonvol_reg r13 + push_nonvol_reg r12 + + // ArgumentRegisters + PUSH_ARGUMENT_REGISTERS + + .if \stackAllocOnEntry >= 3*8 + mov \stackAllocSpill3, [rsp + 0x48] + save_reg_postrsp r15, 0x48 + .endif + + .if \stackAllocOnEntry >= 2*8 + mov \stackAllocSpill2, [rsp + 0x50] + save_reg_postrsp rbx, 0x50 + .endif + + .if \stackAllocOnEntry >= 8 + mov \stackAllocSpill1, [rsp + 0x58] + save_reg_postrsp rbp, 0x58 + lea rbp, [rsp + 0x58] + .endif + + alloc_stack __PWTB_StackAlloc + SAVE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters + + END_PROLOGUE + +.endm + +.macro EPILOG_WITH_TRANSITION_BLOCK_RETURN + + free_stack __PWTB_StackAlloc + POP_ARGUMENT_REGISTERS + POP_CALLEE_SAVED_REGISTERS + ret + +.endm + +.macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL + + RESTORE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters + free_stack __PWTB_StackAlloc + POP_ARGUMENT_REGISTERS + POP_CALLEE_SAVED_REGISTERS + +.endm + +.macro RESET_FRAME_WITH_RBP + + mov rsp, rbp + set_cfa_register rsp, 16 + pop_nonvol_reg rbp + .cfi_same_value rbp + +.endm |