[arch][arm64] add some helpful assembly macros for arm64
Pulled from Fuchsia Zircon kernel code.
This commit is contained in:
@@ -1,13 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Travis Geiselbrecht
|
* Copyright (c) 2014 Travis Geiselbrecht
|
||||||
*
|
* Copyright 2020 The Fuchsia Authors
|
||||||
* Use of this source code is governed by a MIT-style
|
* Use of this source code is governed by a MIT-style
|
||||||
* license that can be found in the LICENSE file or at
|
* license that can be found in the LICENSE file or at
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
#ifdef __ASSEMBLER__ // clang-format off
|
||||||
|
|
||||||
|
#ifndef __has_feature
|
||||||
|
#define __has_feature(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
.macro push ra, rb
|
.macro push ra, rb
|
||||||
stp \ra, \rb, [sp,#-16]!
|
stp \ra, \rb, [sp,#-16]!
|
||||||
.endm
|
.endm
|
||||||
@@ -16,6 +21,84 @@ stp \ra, \rb, [sp,#-16]!
|
|||||||
ldp \ra, \rb, [sp], #16
|
ldp \ra, \rb, [sp], #16
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
/// Fill a register with a wide integer literal.
|
||||||
|
///
|
||||||
|
/// This emits the one to four instructions required to fill a 64-bit
|
||||||
|
/// register with a given bit pattern. It uses as few instructions as
|
||||||
|
/// suffice for the particular value.
|
||||||
|
///
|
||||||
|
/// Parameters
|
||||||
|
///
|
||||||
|
/// * reg
|
||||||
|
/// - Required: Output 64-bit register.
|
||||||
|
///
|
||||||
|
/// * literal
|
||||||
|
/// - Required: An integer expression that can be evaluated immediately
|
||||||
|
/// without relocation.
|
||||||
|
///
|
||||||
|
.macro movlit reg, literal
|
||||||
|
mov \reg, #((\literal) & 0xffff)
|
||||||
|
.ifne (((\literal) >> 16) & 0xffff)
|
||||||
|
movk \reg, #(((\literal) >> 16) & 0xffff), lsl #16
|
||||||
|
.endif
|
||||||
|
.ifne (((\literal) >> 32) & 0xffff)
|
||||||
|
movk \reg, #(((\literal) >> 32) & 0xffff), lsl #32
|
||||||
|
.endif
|
||||||
|
.ifne (((\literal) >> 48) & 0xffff)
|
||||||
|
movk \reg, #(((\literal) >> 48) & 0xffff), lsl #48
|
||||||
|
.endif
|
||||||
|
.endm // movlit
|
||||||
|
|
||||||
|
/// Materialize a symbol (with optional addend) into a register.
|
||||||
|
///
|
||||||
|
/// This emits the `adr` instruction or two-instruction sequence required
|
||||||
|
/// to materialize the address of a global variable or function symbol.
|
||||||
|
///
|
||||||
|
/// Parameters
|
||||||
|
///
|
||||||
|
/// * reg
|
||||||
|
/// - Required: Output 64-bit register.
|
||||||
|
///
|
||||||
|
/// * symbol
|
||||||
|
/// - Required: A symbolic expression requiring at most PC-relative reloc.
|
||||||
|
///
|
||||||
|
.macro adr_global reg, symbol
|
||||||
|
#if __has_feature(hwaddress_sanitizer)
|
||||||
|
adrp \reg, :pg_hi21_nc:\symbol
|
||||||
|
movk \reg, #:prel_g3:\symbol+0x100000000
|
||||||
|
add \reg, \reg, #:lo12:\symbol
|
||||||
|
#elif defined(__AARCH64_CMODEL_TINY__)
|
||||||
|
adr \reg, \symbol
|
||||||
|
#else
|
||||||
|
adrp \reg, \symbol
|
||||||
|
add \reg, \reg, #:lo12:\symbol
|
||||||
|
#endif
|
||||||
|
.endm // adr_global
|
||||||
|
|
||||||
|
/// Load a 64-bit fixed global symbol (with optional addend) into a register.
|
||||||
|
///
|
||||||
|
/// This emits the `ldr` instruction or two-instruction sequence required to
|
||||||
|
/// load a global variable. If multiple words are required, it's more
|
||||||
|
/// efficient to use `adr_global` and then `ldp` than to repeat `ldr_global`
|
||||||
|
/// with related locations.
|
||||||
|
///
|
||||||
|
/// Parameters
|
||||||
|
///
|
||||||
|
/// * reg
|
||||||
|
/// - Required: Output 64-bit register.
|
||||||
|
///
|
||||||
|
/// * symbol
|
||||||
|
/// - Required: A symbolic expression requiring at most PC-relative reloc.
|
||||||
|
///
|
||||||
|
.macro ldr_global reg, symbol
|
||||||
|
#ifdef __AARCH64_CMODEL_TINY__
|
||||||
|
ldr \reg, \symbol
|
||||||
|
#else
|
||||||
|
adrp \reg, \symbol
|
||||||
|
ldr \reg, [\reg, #:lo12:\symbol]
|
||||||
|
#endif
|
||||||
|
.endm // adr_global
|
||||||
|
|
||||||
.macro tbzmask, reg, mask, label, shift=0
|
.macro tbzmask, reg, mask, label, shift=0
|
||||||
.if \shift >= 64
|
.if \shift >= 64
|
||||||
.error "tbzmask: unsupported mask, \mask"
|
.error "tbzmask: unsupported mask, \mask"
|
||||||
@@ -88,3 +171,5 @@ ldp \ra, \rb, [sp], #16
|
|||||||
.quad \handler
|
.quad \handler
|
||||||
.popsection
|
.popsection
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
#endif // __ASSEMBLER__
|
||||||
|
|||||||
Reference in New Issue
Block a user