180709Sjake/*- 280709Sjake * Copyright (c) 2001 Jake Burkholder. 3226054Smarius * Copyright (c) 2011 Marius Strobl <marius@FreeBSD.org> 480709Sjake * All rights reserved. 580709Sjake * 680709Sjake * Redistribution and use in source and binary forms, with or without 780709Sjake * modification, are permitted provided that the following conditions 880709Sjake * are met: 980709Sjake * 1. Redistributions of source code must retain the above copyright 1080709Sjake * notice, this list of conditions and the following disclaimer. 1180709Sjake * 2. Redistributions in binary form must reproduce the above copyright 1280709Sjake * notice, this list of conditions and the following disclaimer in the 1380709Sjake * documentation and/or other materials provided with the distribution. 1480709Sjake * 1581334Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1680709Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1780709Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1881334Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1980709Sjake * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2080709Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2180709Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2280709Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2380709Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2480709Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2580709Sjake * SUCH DAMAGE. 2680709Sjake * 2780709Sjake * $FreeBSD: releng/10.3/sys/sparc64/include/asmacros.h 226054 2011-10-06 11:01:31Z marius $ 2880709Sjake */ 2980709Sjake 3080709Sjake#ifndef _MACHINE_ASMACROS_H_ 3180709Sjake#define _MACHINE_ASMACROS_H_ 3280709Sjake 3380709Sjake#ifdef _KERNEL 3480709Sjake 3588616Sjake/* 3689032Sjake * Normal and alternate %g6 point to the pcb of the current process. Normal, 37216802Smarius * alternate and interrupt %g7 point to per-cpu data. 3888616Sjake */ 3989032Sjake#define PCB_REG %g6 4088616Sjake#define PCPU_REG %g7 4181893Sjake 4288616Sjake/* 4389032Sjake * Alternate %g5 points to a per-cpu panic stack, which is used as a last 4489032Sjake * resort, and for temporarily saving alternate globals. 4588616Sjake */ 4688616Sjake#define ASP_REG %g5 4788616Sjake 4889032Sjake#ifdef LOCORE 4989032Sjake 5088616Sjake/* 5189032Sjake * Atomically decrement an integer in memory. 5288616Sjake */ 53225886Smarius#define ATOMIC_DEC_INT(r1, r2, r3) \ 54225886Smarius lduw [r1], r2 ; \ 55225886Smarius9: sub r2, 1, r3 ; \ 56225886Smarius casa [r1] ASI_N, r2, r3 ; \ 57225886Smarius cmp r2, r3 ; \ 58225886Smarius bne,pn %icc, 9b ; \ 5989032Sjake mov r3, r2 6088616Sjake 6189032Sjake/* 6289032Sjake * Atomically increment an integer in memory. 6389032Sjake */ 64225886Smarius#define ATOMIC_INC_INT(r1, r2, r3) \ 65225886Smarius lduw [r1], r2 ; \ 66225886Smarius9: add r2, 1, r3 ; \ 67225886Smarius casa [r1] ASI_N, r2, r3 ; \ 68225886Smarius cmp r2, r3 ; \ 69225886Smarius bne,pn %icc, 9b ; \ 7089032Sjake mov r3, r2 7189032Sjake 7292198Sjake/* 73225886Smarius * Atomically increment a long in memory. 74117658Sjmg */ 75225886Smarius#define ATOMIC_INC_LONG(r1, r2, r3) \ 76225886Smarius ldx [r1], r2 ; \ 77225886Smarius9: add r2, 1, r3 ; \ 78225886Smarius casxa [r1] ASI_N, r2, r3 ; \ 79225886Smarius cmp r2, r3 ; \ 80225887Smarius bne,pn %xcc, 9b ; \ 81117658Sjmg mov r3, r2 82117658Sjmg 83117658Sjmg/* 8492198Sjake * Atomically clear a number of bits of an integer in memory. 8592198Sjake */ 86225886Smarius#define ATOMIC_CLEAR_INT(r1, r2, r3, bits) \ 87225886Smarius lduw [r1], r2 ; \ 88225886Smarius9: andn r2, bits, r3 ; \ 89225886Smarius casa [r1] ASI_N, r2, r3 ; \ 90225886Smarius cmp r2, r3 ; \ 91225886Smarius bne,pn %icc, 9b ; \ 9292198Sjake mov r3, r2 9392198Sjake 94221750Smarius/* 95225886Smarius * Atomically clear a number of bits of a long in memory. 96221750Smarius */ 97225886Smarius#define ATOMIC_CLEAR_LONG(r1, r2, r3, bits) \ 98225886Smarius ldx [r1], r2 ; \ 99225886Smarius9: andn r2, bits, r3 ; \ 100225886Smarius casxa [r1] ASI_N, r2, r3 ; \ 101225886Smarius cmp r2, r3 ; \ 102226054Smarius bne,pn %xcc, 9b ; \ 103226054Smarius mov r3, r2 104226054Smarius 105226054Smarius/* 106226054Smarius * Atomically load an integer from memory. 107226054Smarius */ 108226054Smarius#define ATOMIC_LOAD_INT(r1, val) \ 109226054Smarius clr val ; \ 110226054Smarius casa [r1] ASI_N, %g0, val 111226054Smarius 112226054Smarius/* 113226054Smarius * Atomically load a long from memory. 114226054Smarius */ 115226054Smarius#define ATOMIC_LOAD_LONG(r1, val) \ 116226054Smarius clr val ; \ 117226054Smarius casxa [r1] ASI_N, %g0, val 118226054Smarius 119226054Smarius/* 120226054Smarius * Atomically set a number of bits of an integer in memory. 121226054Smarius */ 122226054Smarius#define ATOMIC_SET_INT(r1, r2, r3, bits) \ 123226054Smarius lduw [r1], r2 ; \ 124226054Smarius9: or r2, bits, r3 ; \ 125226054Smarius casa [r1] ASI_N, r2, r3 ; \ 126226054Smarius cmp r2, r3 ; \ 127225886Smarius bne,pn %icc, 9b ; \ 128221750Smarius mov r3, r2 129221750Smarius 130226054Smarius/* 131226054Smarius * Atomically set a number of bits of a long in memory. 132226054Smarius */ 133226054Smarius#define ATOMIC_SET_LONG(r1, r2, r3, bits) \ 134226054Smarius ldx [r1], r2 ; \ 135226054Smarius9: or r2, bits, r3 ; \ 136226054Smarius casxa [r1] ASI_N, r2, r3 ; \ 137226054Smarius cmp r2, r3 ; \ 138226054Smarius bne,pn %xcc, 9b ; \ 139226054Smarius mov r3, r2 140226054Smarius 141226054Smarius/* 142226054Smarius * Atomically store an integer in memory. 143226054Smarius */ 144226054Smarius#define ATOMIC_STORE_INT(r1, r2, r3, val) \ 145226054Smarius lduw [r1], r2 ; \ 146226054Smarius9: mov val, r3 ; \ 147226054Smarius casa [r1] ASI_N, r2, r3 ; \ 148226054Smarius cmp r2, r3 ; \ 149226054Smarius bne,pn %icc, 9b ; \ 150226054Smarius mov r3, r2 151226054Smarius 152226054Smarius/* 153226054Smarius * Atomically store a long in memory. 154226054Smarius */ 155226054Smarius#define ATOMIC_STORE_LONG(r1, r2, r3, val) \ 156226054Smarius ldx [r1], r2 ; \ 157226054Smarius9: mov val, r3 ; \ 158226054Smarius casxa [r1] ASI_N, r2, r3 ; \ 159226054Smarius cmp r2, r3 ; \ 160226054Smarius bne,pn %xcc, 9b ; \ 161226054Smarius mov r3, r2 162226054Smarius 16397262Sjake#define PCPU(member) PCPU_REG + PC_ ## member 164225886Smarius#define PCPU_ADDR(member, reg) \ 16597262Sjake add PCPU_REG, PC_ ## member, reg 16684176Sjake 167225886Smarius#define DEBUGGER() \ 16897262Sjake ta %xcc, 1 16984176Sjake 170225886Smarius#define PANIC(msg, r1) \ 171225886Smarius .sect .rodata ; \ 172225886Smarius9: .asciz msg ; \ 173225886Smarius .previous ; \ 174225886Smarius SET(9b, r1, %o0) ; \ 175225886Smarius call panic ; \ 17680709Sjake nop 17780709Sjake 17889032Sjake#ifdef INVARIANTS 179225886Smarius#define KASSERT(r1, msg) \ 180225886Smarius brnz,pt r1, 8f ; \ 181225886Smarius nop ; \ 182225886Smarius PANIC(msg, r1) ; \ 18389032Sjake8: 18489032Sjake#else 18589032Sjake#define KASSERT(r1, msg) 18689032Sjake#endif 18789032Sjake 188225886Smarius#define PUTS(msg, r1) \ 189225886Smarius .sect .rodata ; \ 190225886Smarius9: .asciz msg ; \ 191225886Smarius .previous ; \ 192225886Smarius SET(9b, r1, %o0) ; \ 193225886Smarius call printf ; \ 19488616Sjake nop 19588616Sjake 196100840Sjake#define _ALIGN_DATA .align 8 197100840Sjake 198225886Smarius#define DATA(name) \ 199225886Smarius .data ; \ 200225886Smarius _ALIGN_DATA ; \ 201225886Smarius .globl name ; \ 202225886Smarius .type name, @object ; \ 203114071Sobrienname: 20480709Sjake 20580709Sjake#define EMPTY 20680709Sjake 207216802Smarius/* 208216802Smarius * Generate atomic compare and swap, load and store instructions for the 209216802Smarius * corresponding width and ASI (or not). Note that we want to evaluate the 210216802Smarius * macro args before concatenating, so that EMPTY really turns into nothing. 211216802Smarius */ 212216802Smarius#define _LD(w, a) ld ## w ## a 213216802Smarius#define _ST(w, a) st ## w ## a 214216802Smarius#define _CAS(w, a) cas ## w ## a 215216802Smarius 216216802Smarius#define LD(w, a) _LD(w, a) 217216802Smarius#define ST(w, a) _ST(w, a) 218216802Smarius#define CAS(w, a) _CAS(w, a) 219216802Smarius 22092213Sjake#endif /* LOCORE */ 22192213Sjake 22292213Sjake#endif /* _KERNEL */ 22392213Sjake 22480709Sjake#endif /* !_MACHINE_ASMACROS_H_ */ 225