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