1dnl AMD64 calling conventions checking. 2 3dnl Copyright 2000, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. 4dnl 5dnl This file is part of the GNU MP Library. 6dnl 7dnl The GNU MP Library is free software; you can redistribute it and/or 8dnl modify it under the terms of the GNU Lesser General Public License as 9dnl published by the Free Software Foundation; either version 3 of the 10dnl License, or (at your option) any later version. 11dnl 12dnl The GNU MP Library is distributed in the hope that it will be useful, 13dnl but WITHOUT ANY WARRANTY; without even the implied warranty of 14dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15dnl Lesser General Public License for more details. 16dnl 17dnl You should have received a copy of the GNU Lesser General Public License 18dnl along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. 19 20 21include(`../config.m4') 22 23 24C void x86_fldcw (unsigned short cw); 25C 26C Execute an fldcw, setting the x87 control word to cw. 27 28PROLOGUE(x86_fldcw) 29 movq %rdi, -8(%rsp) 30 fldcw -8(%rsp) 31 ret 32EPILOGUE() 33 34 35C unsigned short x86_fstcw (void); 36C 37C Execute an fstcw, returning the current x87 control word. 38 39PROLOGUE(x86_fstcw) 40 movq $0, -8(%rsp) 41 fstcw -8(%rsp) 42 movq -8(%rsp), %rax 43 ret 44EPILOGUE() 45 46 47dnl Instrumented profiling won't come out quite right below, since we don't 48dnl do an actual "ret". There's only a few instructions here, so there's 49dnl no great need to get them separately accounted, just let them get 50dnl attributed to the caller. 51 52ifelse(WANT_PROFILING,instrument, 53`define(`WANT_PROFILING',no)') 54 55 56C int calling_conventions (...); 57C 58C The global variable "calling_conventions_function" is the function to 59C call, with the arguments as passed here. 60C 61C Perhaps the finit should be done only if the tags word isn't clear, but 62C nothing uses the rounding mode or anything at the moment. 63 64define(`WANT_RBX', eval(8*0)($1)) 65define(`WANT_RBP', eval(8*1)($1)) 66define(`WANT_R12', eval(8*2)($1)) 67define(`WANT_R13', eval(8*3)($1)) 68define(`WANT_R14', eval(8*4)($1)) 69define(`WANT_R15', eval(8*5)($1)) 70 71define(`JUNK_RAX', eval(8*6)($1)) 72define(`JUNK_R10', eval(8*7)($1)) 73define(`JUNK_R11', eval(8*8)($1)) 74 75define(`SAVE_RBX', eval(8*9)($1)) 76define(`SAVE_RBP', eval(8*10)($1)) 77define(`SAVE_R12', eval(8*11)($1)) 78define(`SAVE_R13', eval(8*12)($1)) 79define(`SAVE_R14', eval(8*13)($1)) 80define(`SAVE_R15', eval(8*14)($1)) 81 82define(`RETADDR', eval(8*15)($1)) 83 84define(`RBX', eval(8*16)($1)) 85define(`RBP', eval(8*17)($1)) 86define(`R12', eval(8*18)($1)) 87define(`R13', eval(8*19)($1)) 88define(`R14', eval(8*20)($1)) 89define(`R15', eval(8*21)($1)) 90define(`RFLAGS', eval(8*22)($1)) 91 92 93define(G, 94m4_assert_numargs(1) 95`GSYM_PREFIX`'$1') 96 97 TEXT 98 ALIGN(32) 99PROLOGUE(calling_conventions) 100 push %rdi 101 movq G(calling_conventions_values)@GOTPCREL(%rip), %rdi 102 103 movq 8(%rsp), %rax 104 movq %rax, RETADDR(%rdi) 105 106 leaq L(return)(%rip), %rax 107 movq %rax, 8(%rsp) 108 109 movq %rbx, SAVE_RBX(%rdi) 110 movq %rbp, SAVE_RBP(%rdi) 111 movq %r12, SAVE_R12(%rdi) 112 movq %r13, SAVE_R13(%rdi) 113 movq %r14, SAVE_R14(%rdi) 114 movq %r15, SAVE_R15(%rdi) 115 116 C values we expect to see unchanged, as per amd64check.c 117 movq WANT_RBX(%rdi), %rbx 118 movq WANT_RBP(%rdi), %rbp 119 movq WANT_R12(%rdi), %r12 120 movq WANT_R13(%rdi), %r13 121 movq WANT_R14(%rdi), %r14 122 movq WANT_R15(%rdi), %r15 123 124 C Try to provoke a problem by starting with junk in the registers, 125 C especially %rax which will be the return value. 126 C 127 C ENHANCE-ME: If we knew how many of the parameter registers were 128 C actually being used we could put junk in the rest. Maybe we could 129 C get try.c to communicate this to us. 130C movq JUNK_RAX(%rdi), %rax C overwritten below anyway 131 movq JUNK_R10(%rdi), %r10 132 movq JUNK_R11(%rdi), %r11 133 134 movq G(calling_conventions_function)@GOTPCREL(%rip), %rax 135 pop %rdi 136 jmp *(%rax) 137 138L(return): 139 movq G(calling_conventions_values)@GOTPCREL(%rip), %rdi 140 141 movq %rbx, RBX(%rdi) 142 movq %rbp, RBP(%rdi) 143 movq %r12, R12(%rdi) 144 movq %r13, R13(%rdi) 145 movq %r14, R14(%rdi) 146 movq %r15, R15(%rdi) 147 148 pushfq 149 popq %rbx 150 movq %rbx, RFLAGS(%rdi) 151 152 movq G(calling_conventions_fenv)@GOTPCREL(%rip), %rbx 153 fstenv (%rbx) 154 finit 155 156 movq SAVE_RBX(%rdi), %rbx 157 movq SAVE_RBP(%rdi), %rbp 158 movq SAVE_R12(%rdi), %r12 159 movq SAVE_R13(%rdi), %r13 160 movq SAVE_R14(%rdi), %r14 161 movq SAVE_R15(%rdi), %r15 162 163 jmp *RETADDR(%rdi) 164 165EPILOGUE() 166