| /*************************************************************************** |
| * |
| * x86_64/atomic.s |
| * |
| * $Id$ |
| * |
| *************************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed |
| * with this work for additional information regarding copyright |
| * ownership. The ASF licenses this file to you under the Apache |
| * License, Version 2.0 (the "License"); you may not use this file |
| * except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| * implied. See the License for the specific language governing |
| * permissions and limitations under the License. |
| * |
| * Copyright 2005-2006 Rogue Wave Software. |
| * |
| **************************************************************************/ |
| |
| .text |
| .align 16 |
| |
| /*************************************************************************** |
| * extern "C" int8_t __rw_atomic_xchg8 (int8_t *x, int8_t y); |
| * |
| * Atomically assigns the 8-bit value y to *x and returns |
| * the original (before assignment) 8-bit value of *x. |
| **************************************************************************/ |
| |
| .globl __rw_atomic_xchg8 |
| .type __rw_atomic_xchg8, @function |
| __rw_atomic_xchg8: /* ; int8_t (int8_t *x, int8_t y) */ |
| movq %rdi, %rcx /* ; %rcx = x */ |
| movb %sil, %al /* ; %al = y */ |
| xchgb %al, (%rcx) /* ; %al <-> (%rcx) */ |
| ret |
| |
| |
| /*************************************************************************** |
| * extern "C" int16_t __rw_atomic_xchg16 (int16_t *x, int16_t y); |
| * |
| * Atomically assigns the 16-bit value y to *x and returns |
| * the original (before assignment) 16-bit value of *x. |
| **************************************************************************/ |
| |
| .globl __rw_atomic_xchg16 |
| .type __rw_atomic_xchg16, @function |
| __rw_atomic_xchg16: /* ; int16_t (int16_t *x, int16_t y) */ |
| movq %rdi, %rcx /* ; %rcx = x */ |
| movw %si, %ax /* ; %ax = y */ |
| xchgw %ax, (%rcx) /* ; %ax <-> (%rcx) */ |
| ret |
| |
| |
| /*************************************************************************** |
| * extern "C" int32_t __rw_atomic_xchg32 (int32_t *x, int32_t y); |
| * |
| * Atomically assigns the 32-bit value y to *x and returns |
| * the original (before assignment) 32-bit value of *x. |
| **************************************************************************/ |
| |
| .globl __rw_atomic_xchg32 |
| .type __rw_atomic_xchg32, @function |
| __rw_atomic_xchg32: /* ; int32_t (int32_t *x, int32_t y) */ |
| movq %rdi, %rcx /* ; %rcx = x */ |
| movl %esi, %eax /* ; %eax = y */ |
| xchgl %eax, (%rcx) /* ; %eax <-> (%rcx) */ |
| ret |
| |
| |
| /*************************************************************************** |
| * extern "C" int32_t __rw_atomic_xchg64 (int64_t *x, int64_t y); |
| * |
| * Atomically assigns the 64-bit value y to *x and returns |
| * the original (before assignment) 64-bit value of *x. |
| **************************************************************************/ |
| |
| .globl __rw_atomic_xchg64 |
| .type __rw_atomic_xchg64, @function |
| __rw_atomic_xchg64: /* ; int64_t (int64_t *x, int64_t y) */ |
| movq %rdi, %rcx /* ; %rcx = x */ |
| movq %rsi, %rax /* ; %rax = y */ |
| xchgq %rax, (%rcx) /* ; %rax <-> (%rcx) */ |
| ret |
| |
| |
| /*************************************************************************** |
| * extern "C" int8_t __rw_atomic_add8 (int8_t *x, int8_t y); |
| * |
| * Atomically increments the 8-bit value *x by y and returns |
| * the new (after increment) 8-bit value of *x. |
| **************************************************************************/ |
| |
| .globl __rw_atomic_add8 |
| .type __rw_atomic_add8, @function |
| __rw_atomic_add8: /* ; int8_t (int8_t *dst, int8_t inc) */ |
| movq %rdi, %rcx /* ; %rcx = dst */ |
| movl %esi, %eax /* ; %eax = inc */ |
| movl %eax, %edx /* ; */ |
| |
| lock /* ; lock the bus */ |
| xaddb %al, (%rcx) /* ; tmp = *dst */ |
| /* ; dst += inc */ |
| /* ; %al = tmp */ |
| addl %edx, %eax /* ; return %al + inc */ |
| ret |
| |
| |
| /*************************************************************************** |
| * extern "C" int16_t __rw_atomic_add16 (int16_t *x, int16_t y); |
| * |
| * Atomically increments the 16-bit value *x by y and returns |
| * the new (after increment) 16-bit value of *x. |
| **************************************************************************/ |
| |
| .globl __rw_atomic_add16 |
| .type __rw_atomic_add16, @function |
| __rw_atomic_add16: /* ; int16_t (int16_t *dst, int16_t inc) */ |
| movq %rdi, %rcx /* ; %rcx = dst */ |
| movw %si, %ax /* ; %ax = inc */ |
| movw %ax, %dx /* ; */ |
| |
| lock /* ; lock the bus */ |
| xaddw %ax, (%rcx) /* ; tmp = *dst */ |
| /* ; dst += inc */ |
| /* ; %ax = tmp */ |
| |
| addw %dx, %ax /* ; return %ax + inc */ |
| ret |
| |
| |
| /*************************************************************************** |
| * extern "C" int32_t __rw_atomic_add32 (int32_t *x, int32_t y); |
| * |
| * Atomically increments the 32-bit value *x by y and returns |
| * the new (after increment) 32-bit value of *x. |
| **************************************************************************/ |
| |
| .globl __rw_atomic_add32 |
| .type __rw_atomic_add32, @function |
| __rw_atomic_add32: /* ; int32_t (int32_t *dst, int32_t inc) */ |
| movq %rdi, %rcx /* ; %rcx = dst */ |
| movl %esi, %edx /* ; %edx = inc */ |
| movl %edx, %eax /* ; */ |
| |
| lock /* ; lock the bus */ |
| xaddl %eax, (%rcx) /* ; tmp = *dst */ |
| /* ; dst += inc */ |
| /* ; %eax = tmp */ |
| |
| addl %edx, %eax /* ; return %eax + inc */ |
| ret |
| |
| |
| /*************************************************************************** |
| * extern "C" int64_t __rw_atomic_add64 (int64_t *x, int64_t y); |
| * |
| * Atomically increments the 32-bit value *x by y and returns |
| * the new (after increment) 32-bit value of *x. |
| **************************************************************************/ |
| |
| .globl __rw_atomic_add64 |
| .type __rw_atomic_add64, @function |
| __rw_atomic_add64: /* ; int64_t (int64_t *dst, int64_t inc) */ |
| movq %rdi, %rcx /* ; %rcx = dst */ |
| movq %rsi, %rdx /* ; %edx = inc */ |
| movq %rdx, %rax /* ; */ |
| |
| lock /* ; lock the bus */ |
| xaddq %rax, (%rcx) /* ; tmp = *dst */ |
| /* ; dst += inc */ |
| /* ; %rax = tmp */ |
| |
| addq %rdx, %rax /* ; return %rax + inc */ |
| ret |