asmacros.h revision 171914
11817Sdg/*- 21817Sdg * Copyright (c) 1993 The Regents of the University of California. 31817Sdg * All rights reserved. 41817Sdg * 51817Sdg * Redistribution and use in source and binary forms, with or without 61817Sdg * modification, are permitted provided that the following conditions 71817Sdg * are met: 81817Sdg * 1. Redistributions of source code must retain the above copyright 91817Sdg * notice, this list of conditions and the following disclaimer. 101817Sdg * 2. Redistributions in binary form must reproduce the above copyright 111817Sdg * notice, this list of conditions and the following disclaimer in the 121817Sdg * documentation and/or other materials provided with the distribution. 131817Sdg * 4. Neither the name of the University nor the names of its contributors 141817Sdg * may be used to endorse or promote products derived from this software 151817Sdg * without specific prior written permission. 161817Sdg * 171817Sdg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181817Sdg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191817Sdg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201817Sdg * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211817Sdg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221817Sdg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231817Sdg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241817Sdg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251817Sdg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261817Sdg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271817Sdg * SUCH DAMAGE. 281817Sdg * 2950477Speter * $FreeBSD: head/sys/amd64/include/asmacros.h 171914 2007-08-22 04:26:07Z jkoshy $ 301817Sdg */ 311817Sdg 322579Sbde#ifndef _MACHINE_ASMACROS_H_ 332579Sbde#define _MACHINE_ASMACROS_H_ 342123Sjkh 3516029Speter#include <sys/cdefs.h> 362579Sbde 3718961Sbde/* XXX too much duplication in various asm*.h's. */ 3813107Sbde 3925083Sjdp/* 40163726Sbde * CNAME is used to manage the relationship between symbol names in C 4125083Sjdp * and the equivalent assembly language names. CNAME is given a name as 4225083Sjdp * it would be used in a C program. It expands to the equivalent assembly 43163726Sbde * language name. 4425083Sjdp */ 4525083Sjdp#define CNAME(csym) csym 4625083Sjdp 47114349Speter#define ALIGN_DATA .p2align 3 /* 8 byte alignment, zero filled */ 4822636Sbde#ifdef GPROF 4925083Sjdp#define ALIGN_TEXT .p2align 4,0x90 /* 16-byte alignment, nop filled */ 5022636Sbde#else 51114349Speter#define ALIGN_TEXT .p2align 4,0x90 /* 16-byte alignment, nop filled */ 5222636Sbde#endif 5325083Sjdp#define SUPERALIGN_TEXT .p2align 4,0x90 /* 16-byte alignment, nop filled */ 54757Sdg 5525083Sjdp#define GEN_ENTRY(name) ALIGN_TEXT; .globl CNAME(name); \ 5646548Sbde .type CNAME(name),@function; CNAME(name): 5713107Sbde#define NON_GPROF_ENTRY(name) GEN_ENTRY(name) 5818961Sbde#define NON_GPROF_RET .byte 0xc3 /* opcode for `ret' */ 59757Sdg 60171914Sjkoshy#define END(name) .size name, . - name 61171914Sjkoshy 62757Sdg#ifdef GPROF 63757Sdg/* 6446548Sbde * __mcount is like [.]mcount except that doesn't require its caller to set 6513107Sbde * up a frame pointer. It must be called before pushing anything onto the 6613107Sbde * stack. gcc should eventually generate code to call __mcount in most 6713107Sbde * cases. This would make -pg in combination with -fomit-frame-pointer 6813107Sbde * useful. gcc has a configuration variable PROFILE_BEFORE_PROLOGUE to 6913107Sbde * allow profiling before setting up the frame pointer, but this is 7013107Sbde * inadequate for good handling of special cases, e.g., -fpic works best 7113107Sbde * with profiling after the prologue. 7213107Sbde * 7346548Sbde * [.]mexitcount is a new function to support non-statistical profiling if an 7418961Sbde * accurate clock is available. For C sources, calls to it are generated 7518961Sbde * by the FreeBSD extension `-mprofiler-epilogue' to gcc. It is best to 7646548Sbde * call [.]mexitcount at the end of a function like the MEXITCOUNT macro does, 7718961Sbde * but gcc currently generates calls to it at the start of the epilogue to 7818961Sbde * avoid problems with -fpic. 7913107Sbde * 8046548Sbde * [.]mcount and __mcount may clobber the call-used registers and %ef. 8146548Sbde * [.]mexitcount may clobber %ecx and %ef. 8213107Sbde * 8318961Sbde * Cross-jumping makes non-statistical profiling timing more complicated. 8446548Sbde * It is handled in many cases by calling [.]mexitcount before jumping. It 8546548Sbde * is handled for conditional jumps using CROSSJUMP() and CROSSJUMP_LABEL(). 8618961Sbde * It is handled for some fault-handling jumps by not sharing the exit 8718961Sbde * routine. 8813107Sbde * 8913107Sbde * ALTENTRY() must be before a corresponding ENTRY() so that it can jump to 9013107Sbde * the main entry point. Note that alt entries are counted twice. They 9113107Sbde * have to be counted as ordinary entries for gprof to get the call times 9213107Sbde * right for the ordinary entries. 9313107Sbde * 9413107Sbde * High local labels are used in macros to avoid clashes with local labels 9513107Sbde * in functions. 9613107Sbde * 9718961Sbde * Ordinary `ret' is used instead of a macro `RET' because there are a lot 9818961Sbde * of `ret's. 0xc3 is the opcode for `ret' (`#define ret ... ret' can't 9918961Sbde * be used because this file is sometimes preprocessed in traditional mode). 10018961Sbde * `ret' clobbers eflags but this doesn't matter. 101757Sdg */ 10213107Sbde#define ALTENTRY(name) GEN_ENTRY(name) ; MCOUNT ; MEXITCOUNT ; jmp 9f 10318961Sbde#define CROSSJUMP(jtrue, label, jfalse) \ 10418961Sbde jfalse 8f; MEXITCOUNT; jmp __CONCAT(to,label); 8: 10518961Sbde#define CROSSJUMPTARGET(label) \ 10618961Sbde ALIGN_TEXT; __CONCAT(to,label): ; MCOUNT; jmp label 10713107Sbde#define ENTRY(name) GEN_ENTRY(name) ; 9: ; MCOUNT 108122940Speter#define FAKE_MCOUNT(caller) pushq caller ; call __mcount ; popq %rcx 10913107Sbde#define MCOUNT call __mcount 11013107Sbde#define MCOUNT_LABEL(name) GEN_ENTRY(name) ; nop ; ALIGN_TEXT 111163722Sbde#ifdef GUPROF 112163726Sbde#define MEXITCOUNT call .mexitcount 11318961Sbde#define ret MEXITCOUNT ; NON_GPROF_RET 114163722Sbde#else 115163722Sbde#define MEXITCOUNT 116163722Sbde#endif 11718961Sbde 11818961Sbde#else /* !GPROF */ 119757Sdg/* 120757Sdg * ALTENTRY() has to align because it is before a corresponding ENTRY(). 121757Sdg * ENTRY() has to align to because there may be no ALTENTRY() before it. 12213107Sbde * If there is a previous ALTENTRY() then the alignment code for ENTRY() 12313107Sbde * is empty. 124757Sdg */ 12513107Sbde#define ALTENTRY(name) GEN_ENTRY(name) 12618961Sbde#define CROSSJUMP(jtrue, label, jfalse) jtrue label 12718961Sbde#define CROSSJUMPTARGET(label) 12813107Sbde#define ENTRY(name) GEN_ENTRY(name) 12913107Sbde#define FAKE_MCOUNT(caller) 1301321Sdg#define MCOUNT 13113107Sbde#define MCOUNT_LABEL(name) 13213107Sbde#define MEXITCOUNT 13313107Sbde#endif /* GPROF */ 134757Sdg 135122849Speter#ifdef LOCORE 136122849Speter/* 137156699Speter * Convenience macro for declaring interrupt entry points. 138122849Speter */ 139122849Speter#define IDTVEC(name) ALIGN_TEXT; .globl __CONCAT(X,name); \ 140122849Speter .type __CONCAT(X,name),@function; __CONCAT(X,name): 141122849Speter 142153241Sjhb/* 143153241Sjhb * Macros to create and destroy a trap frame. 144153241Sjhb */ 145153241Sjhb#define PUSH_FRAME \ 146153241Sjhb subq $TF_RIP,%rsp ; /* skip dummy tf_err and tf_trapno */ \ 147153241Sjhb testb $SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */ \ 148153241Sjhb jz 1f ; /* Yes, dont swapgs again */ \ 149153241Sjhb swapgs ; \ 150153241Sjhb1: movq %rdi,TF_RDI(%rsp) ; \ 151153241Sjhb movq %rsi,TF_RSI(%rsp) ; \ 152153241Sjhb movq %rdx,TF_RDX(%rsp) ; \ 153153241Sjhb movq %rcx,TF_RCX(%rsp) ; \ 154153241Sjhb movq %r8,TF_R8(%rsp) ; \ 155153241Sjhb movq %r9,TF_R9(%rsp) ; \ 156153241Sjhb movq %rax,TF_RAX(%rsp) ; \ 157153241Sjhb movq %rbx,TF_RBX(%rsp) ; \ 158153241Sjhb movq %rbp,TF_RBP(%rsp) ; \ 159153241Sjhb movq %r10,TF_R10(%rsp) ; \ 160153241Sjhb movq %r11,TF_R11(%rsp) ; \ 161153241Sjhb movq %r12,TF_R12(%rsp) ; \ 162153241Sjhb movq %r13,TF_R13(%rsp) ; \ 163153241Sjhb movq %r14,TF_R14(%rsp) ; \ 164153241Sjhb movq %r15,TF_R15(%rsp) 165153241Sjhb 166153241Sjhb#define POP_FRAME \ 167153241Sjhb movq TF_RDI(%rsp),%rdi ; \ 168153241Sjhb movq TF_RSI(%rsp),%rsi ; \ 169153241Sjhb movq TF_RDX(%rsp),%rdx ; \ 170153241Sjhb movq TF_RCX(%rsp),%rcx ; \ 171153241Sjhb movq TF_R8(%rsp),%r8 ; \ 172153241Sjhb movq TF_R9(%rsp),%r9 ; \ 173153241Sjhb movq TF_RAX(%rsp),%rax ; \ 174153241Sjhb movq TF_RBX(%rsp),%rbx ; \ 175153241Sjhb movq TF_RBP(%rsp),%rbp ; \ 176153241Sjhb movq TF_R10(%rsp),%r10 ; \ 177153241Sjhb movq TF_R11(%rsp),%r11 ; \ 178153241Sjhb movq TF_R12(%rsp),%r12 ; \ 179153241Sjhb movq TF_R13(%rsp),%r13 ; \ 180153241Sjhb movq TF_R14(%rsp),%r14 ; \ 181153241Sjhb movq TF_R15(%rsp),%r15 ; \ 182153241Sjhb testb $SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */ \ 183153241Sjhb jz 1f ; /* keep kernel GS.base */ \ 184153241Sjhb cli ; \ 185153241Sjhb swapgs ; \ 186153241Sjhb1: addq $TF_RIP,%rsp /* skip over tf_err, tf_trapno */ 187153241Sjhb 188153241Sjhb/* 189153241Sjhb * Access per-CPU data. 190153241Sjhb */ 191153241Sjhb#define PCPU(member) %gs:PC_ ## member 192153241Sjhb#define PCPU_ADDR(member, reg) \ 193153241Sjhb movq %gs:PC_PRVSPACE, reg ; \ 194153241Sjhb addq $PC_ ## member, reg 195153241Sjhb 196122849Speter#endif /* LOCORE */ 197122849Speter 1982579Sbde#endif /* !_MACHINE_ASMACROS_H_ */ 199