Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  asm_support_riscv64.S

  Sprache: Sparc
 

/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed 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.
 */


#ifndef ART_RUNTIME_ARCH_RISCV64_ASM_SUPPORT_RISCV64_S_
#define ART_RUNTIME_ARCH_RISCV64_ASM_SUPPORT_RISCV64_S_

#include "asm_support_riscv64.h"
#include "interpreter/cfi_asm_support.h"

// Define special registers.

// Register holding Thread::Current().
#define xSELF s1


.macro ENTRY name
    .hidden \name  // Hide this as a global symbol, so we do not incur plt calls.
    .global \name
    .balign 16
\name:
    .cfi_startproc
.endm


.macro END name
    .cfi_endproc
    .size \name, .-\name
.endm


.macro UNDEFINED name
    ENTRY \name
        unimp
    END \name
.endm


.macro CFI_REMEMBER_STATE
    .cfi_remember_state
.endm


// The spec is not clear whether the CFA is part of the saved state and tools differ in the
// behaviour, so explicitly set the CFA to avoid any ambiguity.
// The restored CFA state should match the CFA state during CFI_REMEMBER_STATE.
.macro CFI_RESTORE_STATE_AND_DEF_CFA reg, offset
    .cfi_restore_state
    .cfi_def_cfa \reg, \offset
.endm


.macro CFI_EXPRESSION_BREG n, b, offset
    .if (-0x40 <= (\offset)) && ((\offset) < 0x40)
        CFI_EXPRESSION_BREG_1(\n, \b, \offset)
    .elseif (-0x2000 <= (\offset)) && ((\offset) < 0x2000)
        CFI_EXPRESSION_BREG_2(\n, \b, \offset)
    .else
        .error "Unsupported offset"
    .endif
.endm


.macro CFI_DEF_CFA_BREG_PLUS_UCONST reg, offset, size
    .if (((\offset) < -0x40) || ((\offset) >= 0x40))
        .error "Unsupported offset"
    .endif

    .if ((\size) < 0)
        .error "Unsupported size, negative"
    .elseif ((\size) < 0x80)
        CFI_DEF_CFA_BREG_PLUS_UCONST_1_1(\reg, \offset, \size)
    .elseif ((\size) < 0x4000)
        CFI_DEF_CFA_BREG_PLUS_UCONST_1_2(\reg, \offset, \size)
    .else
        .error "Unsupported size, too large"
    .endif
.endm


// Macro to poison (negate) the reference for heap poisoning.
.macro POISON_HEAP_REF ref
#ifdef USE_HEAP_POISONING
    neg \ref, \ref
    zext.w \ref, \ref
#endif  // USE_HEAP_POISONING
.endm


// Macro to unpoison (negate) the reference for heap poisoning.
.macro UNPOISON_HEAP_REF ref
#ifdef USE_HEAP_POISONING
    neg \ref, \ref
    zext.w \ref, \ref
#endif  // USE_HEAP_POISONING
.endm


.macro INCREASE_FRAME frame_adjustment
    addi sp, sp, -(\frame_adjustment)
    .cfi_adjust_cfa_offset (\frame_adjustment)
.endm


.macro DECREASE_FRAME frame_adjustment
    addi sp, sp, (\frame_adjustment)
    .cfi_adjust_cfa_offset -(\frame_adjustment)
.endm


.macro SAVE_GPR_BASE base, reg, offset
    sd \reg, (\offset)(\base)
    .cfi_rel_offset \reg, (\offset)
.endm


.macro SAVE_GPR reg, offset
    SAVE_GPR_BASE sp, \reg, \offset
.endm


.macro RESTORE_GPR_BASE base, reg, offset
    ld \reg, (\offset)(\base)
    .cfi_restore \reg
.endm


.macro RESTORE_GPR reg, offset
    RESTORE_GPR_BASE sp, \reg, \offset
.endm


.macro RESTORE_GPR_NE skip, reg, offset
    .ifnc \skip, \reg
    RESTORE_GPR_BASE sp, \reg, \offset
    .endif
.endm


.macro SAVE_FPR reg, offset
    fsd \reg, (\offset)(sp)
    .cfi_rel_offset \reg, (\offset)
.endm


.macro RESTORE_FPR reg, offset
    fld \reg, (\offset)(sp)
    .cfi_restore \reg
.endm


// 8 argument GPRS: a0 - a7 and 8 argument FPRs: fa0 - fa7
#define ALL_ARGS_SIZE (8 * (8 + 8))


.macro SAVE_ALL_ARGS_INCREASE_FRAME extra_space
    // Reserve space for all argument registers, plus the extra space.
    INCREASE_FRAME (ALL_ARGS_SIZE + \extra_space)

    // Argument GPRs a0 - a7.
    sd    a0, (8*0)(sp)
    sd    a1, (8*1)(sp)
    sd    a2, (8*2)(sp)
    sd    a3, (8*3)(sp)
    sd    a4, (8*4)(sp)
    sd    a5, (8*5)(sp)
    sd    a6, (8*6)(sp)
    sd    a7, (8*7)(sp)

    // Argument FPRs fa0 - fa7.
    fsd   fa0, (8*8)(sp)
    fsd   fa1, (8*9)(sp)
    fsd   fa2, (8*10)(sp)
    fsd   fa3, (8*11)(sp)
    fsd   fa4, (8*12)(sp)
    fsd   fa5, (8*13)(sp)
    fsd   fa6, (8*14)(sp)
    fsd   fa7, (8*15)(sp)
.endm


.macro RESTORE_ALL_ARGS_DECREASE_FRAME extra_space
    // Argument GPRs a0 - a7.
    ld    a0, (8*0)(sp)
    ld    a1, (8*1)(sp)
    ld    a2, (8*2)(sp)
    ld    a3, (8*3)(sp)
    ld    a4, (8*4)(sp)
    ld    a5, (8*5)(sp)
    ld    a6, (8*6)(sp)
    ld    a7, (8*7)(sp)

    // Argument FPRs fa0 - fa7.
    fld   fa0, (8*8)(sp)
    fld   fa1, (8*9)(sp)
    fld   fa2, (8*10)(sp)
    fld   fa3, (8*11)(sp)
    fld   fa4, (8*12)(sp)
    fld   fa5, (8*13)(sp)
    fld   fa6, (8*14)(sp)
    fld   fa7, (8*15)(sp)

    DECREASE_FRAME (ALL_ARGS_SIZE + \extra_space)
.endm


.macro LOAD_RUNTIME_INSTANCE reg
#if __has_feature(hwaddress_sanitizer)
#error "ART does not support HWASAN on RISC-V yet"
#else
    la \reg, _ZN3art7Runtime9instance_E
#endif
    ld \reg, 0(\reg)
.endm


// We need to save callee-save GPRs on the stack as they may contain references, and must be
// visible to GC (unless the called method holds mutator lock and prevents GC from happening).
// FP callee-saves shall be preserved by whatever runtime function we call, so they do not need
// to be saved.
.macro SETUP_SAVE_REFS_AND_ARGS_FRAME_INTERNAL
#if (FRAME_SIZE_SAVE_REFS_AND_ARGS != 8*(1 + 8 + 7 + 11 + 1))
#error "FRAME_SIZE_SAVE_REFS_AND_ARGS(RISCV64) size not as expected."
#endif
    // stack slot (0*8)(sp) is for ArtMethod*

    SAVE_FPR fa0, (1*8)
    SAVE_FPR fa1, (2*8)
    SAVE_FPR fa2, (3*8)
    SAVE_FPR fa3, (4*8)
    SAVE_FPR fa4, (5*8)
    SAVE_FPR fa5, (6*8)
    SAVE_FPR fa6, (7*8)
    SAVE_FPR fa7, (8*8)

    SAVE_GPR fp,  (9*8)  // x8, frame pointer
    // s1 (x9) is the ART thread register

    // a0 (x10) is the method pointer
    SAVE_GPR a1,  (10*8)  // x11
    SAVE_GPR a2,  (11*8)  // x12
    SAVE_GPR a3,  (12*8)  // x13
    SAVE_GPR a4,  (13*8)  // x14
    SAVE_GPR a5,  (14*8)  // x15
    SAVE_GPR a6,  (15*8)  // x16
    SAVE_GPR a7,  (16*8)  // x17

    SAVE_GPR s2,  (17*8)  // x18
    SAVE_GPR s3,  (18*8)  // x19
    SAVE_GPR s4,  (19*8)  // x20
    SAVE_GPR s5,  (20*8)  // x21
    SAVE_GPR s6,  (21*8)  // x22
    SAVE_GPR s7,  (22*8)  // x23
    SAVE_GPR s8,  (23*8)  // x24
    SAVE_GPR s9,  (24*8)  // x25
    SAVE_GPR s10, (25*8)  // x26
    SAVE_GPR s11, (26*8)  // x27

    SAVE_GPR ra,  (27*8)  // x1, return address
.endm


.macro RESTORE_SAVE_REFS_AND_ARGS_FRAME_INTERNAL
    // stack slot (0*8)(sp) is for ArtMethod*

    RESTORE_FPR fa0, (1*8)
    RESTORE_FPR fa1, (2*8)
    RESTORE_FPR fa2, (3*8)
    RESTORE_FPR fa3, (4*8)
    RESTORE_FPR fa4, (5*8)
    RESTORE_FPR fa5, (6*8)
    RESTORE_FPR fa6, (7*8)
    RESTORE_FPR fa7, (8*8)

    RESTORE_GPR fp,  (9*8)  // x8, frame pointer

    // a0 is the method pointer
    RESTORE_GPR a1,  (10*8)  // x11
    RESTORE_GPR a2,  (11*8)  // x12
    RESTORE_GPR a3,  (12*8)  // x13
    RESTORE_GPR a4,  (13*8)  // x14
    RESTORE_GPR a5,  (14*8)  // x15
    RESTORE_GPR a6,  (15*8)  // x16
    RESTORE_GPR a7,  (16*8)  // x17

    // s1 is the ART thread register
    RESTORE_GPR s2,  (17*8)  // x18
    RESTORE_GPR s3,  (18*8)  // x19
    RESTORE_GPR s4,  (19*8)  // x20
    RESTORE_GPR s5,  (20*8)  // x21
    RESTORE_GPR s6,  (21*8)  // x22
    RESTORE_GPR s7,  (22*8)  // x23
    RESTORE_GPR s8,  (23*8)  // x24
    RESTORE_GPR s9,  (24*8)  // x25
    RESTORE_GPR s10, (25*8)  // x26
    RESTORE_GPR s11, (26*8)  // x27

    RESTORE_GPR ra,  (27*8)  // x1, return address
.endm


.macro SETUP_CALLEE_SAVE_FRAME_COMMON_INTERNAL reg
    // ArtMethod* is in reg, store it at the bottom of the stack.
    sd \reg, (sp)

    // Place sp in Thread::Current()->top_quick_frame.
    sd sp, THREAD_TOP_QUICK_FRAME_OFFSET(xSELF)
.endm


.macro SETUP_CALLEE_SAVE_FRAME_COMMON tmpreg, runtime_method_offset
    // art::Runtime* tmpreg = art::Runtime::instance_;
    LOAD_RUNTIME_INSTANCE \tmpreg

    // ArtMethod* tmpreg = Runtime::instance_->callee_save_methods_[<callee-save-frame-type>];
    ld  \tmpreg, \runtime_method_offset(\tmpreg)

    SETUP_CALLEE_SAVE_FRAME_COMMON_INTERNAL \tmpreg
.endm


.macro SETUP_SAVE_REFS_AND_ARGS_FRAME
    INCREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS
    SETUP_SAVE_REFS_AND_ARGS_FRAME_INTERNAL
    SETUP_CALLEE_SAVE_FRAME_COMMON t0, RUNTIME_SAVE_REFS_AND_ARGS_METHOD_OFFSET
.endm


.macro SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_A0
    INCREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS
    SETUP_SAVE_REFS_AND_ARGS_FRAME_INTERNAL
    SETUP_CALLEE_SAVE_FRAME_COMMON_INTERNAL a0
.endm


.macro RESTORE_SAVE_REFS_AND_ARGS_FRAME
    RESTORE_SAVE_REFS_AND_ARGS_FRAME_INTERNAL
    DECREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS
.endm


.macro SAVE_ALL_CALLEE_SAVES
#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVES != 8*(12 + 11 + 1 + 1 + 1))
#error "FRAME_SIZE_SAVE_ALL_CALLEE_SAVES(RISCV64) size not as expected."
#endif
    // stack slot (0*8)(sp) is for ArtMethod*
    // stack slot (1*8)(sp) is for padding

    // FP callee-saves.
    SAVE_FPR fs0,  (8*2)   // f8
    SAVE_FPR fs1,  (8*3)   // f9
    SAVE_FPR fs2,  (8*4)   // f18
    SAVE_FPR fs3,  (8*5)   // f19
    SAVE_FPR fs4,  (8*6)   // f20
    SAVE_FPR fs5,  (8*7)   // f21
    SAVE_FPR fs6,  (8*8)   // f22
    SAVE_FPR fs7,  (8*9)   // f23
    SAVE_FPR fs8,  (8*10)  // f24
    SAVE_FPR fs9,  (8*11)  // f25
    SAVE_FPR fs10, (8*12)  // f26
    SAVE_FPR fs11, (8*13)  // f27

    // GP callee-saves
    SAVE_GPR s0,  (8*14)  // x8/fp, frame pointer
    // s1 (x9) is the ART thread register
    SAVE_GPR s2,  (8*15)  // x18
    SAVE_GPR s3,  (8*16)  // x19
    SAVE_GPR s4,  (8*17)  // x20
    SAVE_GPR s5,  (8*18)  // x21
    SAVE_GPR s6,  (8*19)  // x22
    SAVE_GPR s7,  (8*20)  // x23
    SAVE_GPR s8,  (8*21)  // x24
    SAVE_GPR s9,  (8*22)  // x25
    SAVE_GPR s10, (8*23)  // x26
    SAVE_GPR s11, (8*24)  // x27

    SAVE_GPR ra,  (8*25)  // x1, return address
.endm


.macro RESTORE_ALL_CALLEE_SAVES
#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVES != 8*(12 + 11 + 1 + 1 + 1))
#error "FRAME_SIZE_SAVE_ALL_CALLEE_SAVES(RISCV64) size not as expected."
#endif
    // stack slot (8*0)(sp) is for ArtMethod*
    // stack slot (8*1)(sp) is for padding

    // FP callee-saves.
    RESTORE_FPR fs0,  (8*2)   // f8
    RESTORE_FPR fs1,  (8*3)   // f9
    RESTORE_FPR fs2,  (8*4)   // f18
    RESTORE_FPR fs3,  (8*5)   // f19
    RESTORE_FPR fs4,  (8*6)   // f20
    RESTORE_FPR fs5,  (8*7)   // f21
    RESTORE_FPR fs6,  (8*8)   // f22
    RESTORE_FPR fs7,  (8*9)   // f23
    RESTORE_FPR fs8,  (8*10)  // f24
    RESTORE_FPR fs9,  (8*11)  // f25
    RESTORE_FPR fs10, (8*12)  // f26
    RESTORE_FPR fs11, (8*13)  // f27

    // GP callee-saves
    RESTORE_GPR s0,  (8*14)  // x8/fp, frame pointer
    // s1 is the ART thread register
    RESTORE_GPR s2,  (8*15)  // x18
    RESTORE_GPR s3,  (8*16)  // x19
    RESTORE_GPR s4,  (8*17)  // x20
    RESTORE_GPR s5,  (8*18)  // x21
    RESTORE_GPR s6,  (8*19)  // x22
    RESTORE_GPR s7,  (8*20)  // x23
    RESTORE_GPR s8,  (8*21)  // x24
    RESTORE_GPR s9,  (8*22)  // x25
    RESTORE_GPR s10, (8*23)  // x26
    RESTORE_GPR s11, (8*24)  // x27

    RESTORE_GPR ra,  (8*25)  // x1, return address
.endm


.macro SETUP_SAVE_ALL_CALLEE_SAVES_FRAME
    INCREASE_FRAME FRAME_SIZE_SAVE_ALL_CALLEE_SAVES
    SAVE_ALL_CALLEE_SAVES
    SETUP_CALLEE_SAVE_FRAME_COMMON t0, RUNTIME_SAVE_ALL_CALLEE_SAVES_METHOD_OFFSET
.endm


.macro SETUP_SAVE_EVERYTHING_FRAME_DECREMENTED_SP_SKIP_RA \
        runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET
#if (FRAME_SIZE_SAVE_EVERYTHING != 8*(1 + 32 + 27))
#error "FRAME_SIZE_SAVE_EVERYTHING(RISCV64) size not as expected."
#endif
    // stack slot (8*0)(sp) is for ArtMethod*

    // 32 slots for FPRs
    SAVE_FPR ft0,  8*1   // f0
    SAVE_FPR ft1,  8*2   // f1
    SAVE_FPR ft2,  8*3   // f2
    SAVE_FPR ft3,  8*4   // f3
    SAVE_FPR ft4,  8*5   // f4
    SAVE_FPR ft5,  8*6   // f5
    SAVE_FPR ft6,  8*7   // f6
    SAVE_FPR ft7,  8*8   // f7
    SAVE_FPR fs0,  8*9   // f8
    SAVE_FPR fs1,  8*10  // f9
#define SAVE_EVERYTHING_FRAME_OFFSET_FA0 (8*11)
    SAVE_FPR fa0,  8*11  // f10, its offset must equal SAVE_EVERYTHING_FRAME_OFFSET_FA0
    SAVE_FPR fa1,  8*12  // f11
    SAVE_FPR fa2,  8*13  // f12
    SAVE_FPR fa3,  8*14  // f13
    SAVE_FPR fa4,  8*15  // f14
    SAVE_FPR fa5,  8*16  // f15
    SAVE_FPR fa6,  8*17  // f16
    SAVE_FPR fa7,  8*18  // f17
    SAVE_FPR fs2,  8*19  // f18
    SAVE_FPR fs3,  8*20  // f19
    SAVE_FPR fs4,  8*21  // f20
    SAVE_FPR fs5,  8*22  // f21
    SAVE_FPR fs6,  8*23  // f22
    SAVE_FPR fs7,  8*24  // f23
    SAVE_FPR fs8,  8*25  // f24
    SAVE_FPR fs9,  8*26  // f25
    SAVE_FPR fs10, 8*27  // f26
    SAVE_FPR fs11, 8*28  // f27
    SAVE_FPR ft8,  8*29  // f28
    SAVE_FPR ft9,  8*30  // f29
    SAVE_FPR ft10, 8*31  // f30
    SAVE_FPR ft11, 8*32  // f31

    // 27 slots for GPRs (excluded: zero/x0, sp/x2, gp/x3, tp/x4, s1/x9 -- the ART thread register)
    SAVE_GPR t0,  8*33  // x5
    SAVE_GPR t1,  8*34  // x6
    SAVE_GPR t2,  8*35  // x7
    SAVE_GPR s0,  8*36  // x8
#define SAVE_EVERYTHING_FRAME_OFFSET_A0 (8*37)
    SAVE_GPR a0,  8*37  // x10, its offset must equal SAVE_EVERYTHING_FRAME_OFFSET_A0
    SAVE_GPR a1,  8*38  // x11
    SAVE_GPR a2,  8*39  // x12
    SAVE_GPR a3,  8*40  // x13
    SAVE_GPR a4,  8*41  // x14
    SAVE_GPR a5,  8*42  // x15
    SAVE_GPR a6,  8*43  // x16
    SAVE_GPR a7,  8*44  // x17
    SAVE_GPR s2,  8*45  // x18
    SAVE_GPR s3,  8*46  // x19
    SAVE_GPR s4,  8*47  // x20
    SAVE_GPR s5,  8*48  // x21
    SAVE_GPR s6,  8*49  // x22
    SAVE_GPR s7,  8*50  // x23
    SAVE_GPR s8,  8*51  // x24
    SAVE_GPR s9,  8*52  // x25
    SAVE_GPR s10, 8*53  // x26
    SAVE_GPR s11, 8*54  // x27
    SAVE_GPR t3,  8*55  // x28
    SAVE_GPR t4,  8*56  // x29
    SAVE_GPR t5,  8*57  // x30
    SAVE_GPR t6,  8*58  // x31

    // RA already saved by the user of this macro.

    SETUP_CALLEE_SAVE_FRAME_COMMON t0, \runtime_method_offset
.endm


.macro SETUP_SAVE_EVERYTHING_FRAME runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET
#if (FRAME_SIZE_SAVE_EVERYTHING != 8*(1 + 32 + 27))
#error "FRAME_SIZE_SAVE_EVERYTHING(RISCV64) size not as expected."
#endif
    INCREASE_FRAME FRAME_SIZE_SAVE_EVERYTHING
    SAVE_GPR ra,  8*59  // x1, return address
    SETUP_SAVE_EVERYTHING_FRAME_DECREMENTED_SP_SKIP_RA \runtime_method_offset
.endm


.macro RESTORE_SAVE_EVERYTHING_FRAME load_a0 = 1
    // stack slot (8*0)(sp) is for ArtMethod*

    // 32 slots for FPRs
    RESTORE_FPR ft0,  (8*1)   // f0
    RESTORE_FPR ft1,  (8*2)   // f1
    RESTORE_FPR ft2,  (8*3)   // f2
    RESTORE_FPR ft3,  (8*4)   // f3
    RESTORE_FPR ft4,  (8*5)   // f4
    RESTORE_FPR ft5,  (8*6)   // f5
    RESTORE_FPR ft6,  (8*7)   // f6
    RESTORE_FPR ft7,  (8*8)   // f7
    RESTORE_FPR fs0,  (8*9)   // f8
    RESTORE_FPR fs1,  (8*10)  // f9
#if SAVE_EVERYTHING_FRAME_OFFSET_FA0 != (8*11)
#error "unexpected SAVE_EVERYTHING_FRAME_OFFSET_FA0"
#endif
    RESTORE_FPR fa0,  (8*11)  // f10, offset must equal SAVE_EVERYTHING_FRAME_OFFSET_FA0
    RESTORE_FPR fa1,  (8*12)  // f11
    RESTORE_FPR fa2,  (8*13)  // f12
    RESTORE_FPR fa3,  (8*14)  // f13
    RESTORE_FPR fa4,  (8*15)  // f14
    RESTORE_FPR fa5,  (8*16)  // f15
    RESTORE_FPR fa6,  (8*17)  // f16
    RESTORE_FPR fa7,  (8*18)  // f17
    RESTORE_FPR fs2,  (8*19)  // f18
    RESTORE_FPR fs3,  (8*20)  // f19
    RESTORE_FPR fs4,  (8*21)  // f20
    RESTORE_FPR fs5,  (8*22)  // f21
    RESTORE_FPR fs6,  (8*23)  // f22
    RESTORE_FPR fs7,  (8*24)  // f23
    RESTORE_FPR fs8,  (8*25)  // f24
    RESTORE_FPR fs9,  (8*26)  // f25
    RESTORE_FPR fs10, (8*27)  // f26
    RESTORE_FPR fs11, (8*28)  // f27
    RESTORE_FPR ft8,  (8*29)  // f28
    RESTORE_FPR ft9,  (8*30)  // f29
    RESTORE_FPR ft10, (8*31)  // f30
    RESTORE_FPR ft11, (8*32)  // f31

    // 26 slots for GPRs (excluded: zero/x0, sp/x2, gp/x3, tp/x4, s1/x9 -- the ART thread register)
    RESTORE_GPR t0,  (8*33)  // x5
    RESTORE_GPR t1,  (8*34)  // x6
    RESTORE_GPR t2,  (8*35)  // x7
    RESTORE_GPR s0,  (8*36)  // x8
#if SAVE_EVERYTHING_FRAME_OFFSET_A0 != (8*37)
#error "unexpected SAVE_EVERYTHING_FRAME_OFFSET_A0"
#endif
    .if \load_a0
    RESTORE_GPR a0,  (8*37)  // x10, offset must equal SAVE_EVERYTHING_FRAME_OFFSET_A0
    .endif
    RESTORE_GPR a1,  (8*38)  // x11
    RESTORE_GPR a2,  (8*39)  // x12
    RESTORE_GPR a3,  (8*40)  // x13
    RESTORE_GPR a4,  (8*41)  // x14
    RESTORE_GPR a5,  (8*42)  // x15
    RESTORE_GPR a6,  (8*43)  // x16
    RESTORE_GPR a7,  (8*44)  // x17
    RESTORE_GPR s2,  (8*45)  // x18
    RESTORE_GPR s3,  (8*46)  // x19
    RESTORE_GPR s4,  (8*47)  // x20
    RESTORE_GPR s5,  (8*48)  // x21
    RESTORE_GPR s6,  (8*49)  // x22
    RESTORE_GPR s7,  (8*50)  // x23
    RESTORE_GPR s8,  (8*51)  // x24
    RESTORE_GPR s9,  (8*52)  // x25
    RESTORE_GPR s10, (8*53)  // x26
    RESTORE_GPR s11, (8*54)  // x27
    RESTORE_GPR t3,  (8*55)  // x28
    RESTORE_GPR t4,  (8*56)  // x29
    RESTORE_GPR t5,  (8*57)  // x30
    RESTORE_GPR t6,  (8*58)  // x31

    RESTORE_GPR ra,  (8*59)  // x1, return address

    DECREASE_FRAME FRAME_SIZE_SAVE_EVERYTHING
.endm


// For compatibility with Runtime::CreateCalleeSaveMethod(kSaveRefsOnly).
.macro SETUP_SAVE_REFS_ONLY_FRAME
    INCREASE_FRAME FRAME_SIZE_SAVE_REFS_ONLY

    // stack slot (8*0)(sp) is for ArtMethod*
    // stack slot (8*1)(sp) is for padding
    SAVE_GPR s0,  (8*2)   // x8
    SAVE_GPR s2,  (8*3)   // x18
    SAVE_GPR s3,  (8*4)   // x19
    SAVE_GPR s4,  (8*5)   // x20
    SAVE_GPR s5,  (8*6)   // x21
    SAVE_GPR s6,  (8*7)   // x22
    SAVE_GPR s7,  (8*8)   // x23
    SAVE_GPR s8,  (8*9)   // x24
    SAVE_GPR s9,  (8*10)  // x25
    SAVE_GPR s10, (8*11)  // x26
    SAVE_GPR s11, (8*12)  // x27
    SAVE_GPR ra,  (8*13)  // x1

    SETUP_CALLEE_SAVE_FRAME_COMMON t0, RUNTIME_SAVE_REFS_ONLY_METHOD_OFFSET
.endm


.macro RESTORE_SAVE_REFS_ONLY_FRAME
    // stack slot (8*0)(sp) is for ArtMethod*
    // stack slot (8*1)(sp) is for padding
    RESTORE_GPR s0,  (8*2)   // x8
    RESTORE_GPR s2,  (8*3)   // x18
    RESTORE_GPR s3,  (8*4)   // x19
    RESTORE_GPR s4,  (8*5)   // x20
    RESTORE_GPR s5,  (8*6)   // x21
    RESTORE_GPR s6,  (8*7)   // x22
    RESTORE_GPR s7,  (8*8)   // x23
    RESTORE_GPR s8,  (8*9)   // x24
    RESTORE_GPR s9,  (8*10)  // x25
    RESTORE_GPR s10, (8*11)  // x26
    RESTORE_GPR s11, (8*12)  // x27
    RESTORE_GPR ra,  (8*13)  // x1

    DECREASE_FRAME FRAME_SIZE_SAVE_REFS_ONLY
.endm


// CFI note. This macro is used where the CFA rule is a dwarf expression, so adjustment of SP does
// not affect CFA computation. We also elide CFI descriptors for the argument registers, because
// they can be recovered from the stack in a debugging scenario.
.macro SPILL_ALL_ARGUMENTS
#if (FRAME_SIZE_SAVE_ARGS_ONLY != 128)
#error "FRAME_SIZE_SAVE_ARGS_ONLY(riscv64) not as expected."
#endif
    addi sp, sp, -FRAME_SIZE_SAVE_ARGS_ONLY
    sd a0,   (8*0)(sp)
    sd a1,   (8*1)(sp)
    sd a2,   (8*2)(sp)
    sd a3,   (8*3)(sp)
    sd a4,   (8*4)(sp)
    sd a5,   (8*5)(sp)
    sd a6,   (8*6)(sp)
    sd a7,   (8*7)(sp)
    fsd fa0, (8*8)(sp)
    fsd fa1, (8*9)(sp)
    fsd fa2, (8*10)(sp)
    fsd fa3, (8*11)(sp)
    fsd fa4, (8*12)(sp)
    fsd fa5, (8*13)(sp)
    fsd fa6, (8*14)(sp)
    fsd fa7, (8*15)(sp)
.endm


.macro RESTORE_ALL_ARGUMENTS
    ld a0,   (8*0)(sp)
    ld a1,   (8*1)(sp)
    ld a2,   (8*2)(sp)
    ld a3,   (8*3)(sp)
    ld a4,   (8*4)(sp)
    ld a5,   (8*5)(sp)
    ld a6,   (8*6)(sp)
    ld a7,   (8*7)(sp)
    fld fa0, (8*8)(sp)
    fld fa1, (8*9)(sp)
    fld fa2, (8*10)(sp)
    fld fa3, (8*11)(sp)
    fld fa4, (8*12)(sp)
    fld fa5, (8*13)(sp)
    fld fa6, (8*14)(sp)
    fld fa7, (8*15)(sp)
    addi sp, sp, FRAME_SIZE_SAVE_ARGS_ONLY
.endm


.macro SETUP_NTERP_SAVE_CALLEE_SAVES
#if (NTERP_SIZE_SAVE_CALLEE_SAVES != 8*(12 + 1 + 10 + 1))
#error "NTERP_SIZE_SAVE_CALLEE_SAVES(RISCV64) size not as expected."
#endif
    // FP callee-saves.
    SAVE_FPR fs0,  (8*0)   // f8
    SAVE_FPR fs1,  (8*1)   // f9
    SAVE_FPR fs2,  (8*2)   // f18
    SAVE_FPR fs3,  (8*3)   // f19
    SAVE_FPR fs4,  (8*4)   // f20
    SAVE_FPR fs5,  (8*5)   // f21
    SAVE_FPR fs6,  (8*6)   // f22
    SAVE_FPR fs7,  (8*7)   // f23
    SAVE_FPR fs8,  (8*8)   // f24
    SAVE_FPR fs9,  (8*9)   // f25
    SAVE_FPR fs10, (8*10)  // f26
    SAVE_FPR fs11, (8*11)  // f27

    // GP callee-saves
    SAVE_GPR s0,  (8*12)  // x8/fp, frame pointer
    // s1 (x9) is the ART thread register
    SAVE_GPR s2,  (8*13)  // x18
    SAVE_GPR s3,  (8*14)  // x19
    SAVE_GPR s4,  (8*15)  // x20
    SAVE_GPR s5,  (8*16)  // x21
    SAVE_GPR s6,  (8*17)  // x22
    SAVE_GPR s7,  (8*18)  // x23
    SAVE_GPR s8,  (8*19)  // x24
    SAVE_GPR s9,  (8*20)  // x25
    SAVE_GPR s10, (8*21)  // x26
    SAVE_GPR s11, (8*22)  // x27

    SAVE_GPR ra,  (8*23)  // x1, return address
.endm


.macro RESTORE_NTERP_SAVE_CALLEE_SAVES
#if (NTERP_SIZE_SAVE_CALLEE_SAVES != 8*(12 + 1 + 10 + 1))
#error "NTERP_SIZE_SAVE_CALLEE_SAVES(RISCV64) size not as expected."
#endif
    // FP callee-saves.
    RESTORE_FPR fs0,  (8*0)   // f8
    RESTORE_FPR fs1,  (8*1)   // f9
    RESTORE_FPR fs2,  (8*2)   // f18
    RESTORE_FPR fs3,  (8*3)   // f19
    RESTORE_FPR fs4,  (8*4)   // f20
    RESTORE_FPR fs5,  (8*5)   // f21
    RESTORE_FPR fs6,  (8*6)   // f22
    RESTORE_FPR fs7,  (8*7)   // f23
    RESTORE_FPR fs8,  (8*8)   // f24
    RESTORE_FPR fs9,  (8*9)   // f25
    RESTORE_FPR fs10, (8*10)  // f26
    RESTORE_FPR fs11, (8*11)  // f27

    // GP callee-saves
    RESTORE_GPR s0,  (8*12)  // x8/fp, frame pointer
    // s1 is the ART thread register
    RESTORE_GPR s2,  (8*13)  // x18
    RESTORE_GPR s3,  (8*14)  // x19
    RESTORE_GPR s4,  (8*15)  // x20
    RESTORE_GPR s5,  (8*16)  // x21
    RESTORE_GPR s6,  (8*17)  // x22
    RESTORE_GPR s7,  (8*18)  // x23
    RESTORE_GPR s8,  (8*19)  // x24
    RESTORE_GPR s9,  (8*20)  // x25
    RESTORE_GPR s10, (8*21)  // x26
    RESTORE_GPR s11, (8*22)  // x27

    RESTORE_GPR ra,  (8*23)  // x1, return address
.endm


// Macro that calls through to artDeliverPendingExceptionFromCode, where the pending exception is
// Thread::Current()->exception_ when the runtime method frame is ready.
.macro DELIVER_PENDING_EXCEPTION_FRAME_READY
    mv a0, xSELF
    call artDeliverPendingExceptionFromCode
    call art_quick_do_long_jump   // (Context*)
    unimp  // Unreached
.endm


// Macro that calls through to artDeliverPendingExceptionFromCode, where the pending exception is
// Thread::Current()->exception_.
.macro DELIVER_PENDING_EXCEPTION
    SETUP_SAVE_ALL_CALLEE_SAVES_FRAME
    DELIVER_PENDING_EXCEPTION_FRAME_READY
.endm


.macro RETURN_OR_DELIVER_PENDING_EXCEPTION_REG reg
    ld \reg, THREAD_EXCEPTION_OFFSET(xSELF)
    bnez \reg, 1f
    ret
1:
    DELIVER_PENDING_EXCEPTION
.endm

// Macro to emit a single LUI to load the given value while checking that the low 12 bits are zero.
.macro LUI_VALUE reg, value
    .if (\value & 0xfff) != 0
    .error "Cannot use LUI to materialize a value with some of the low 12 bits set."
    .endif
    lui \reg, (\value) >> 12
.endm


// Locking is needed for both managed code and JNI stubs.
.macro LOCK_OBJECT_FAST_PATH obj, slow_lock, can_be_null
    // Use scratch registers T1-T6 as temporaries.
    // Note: T0 is used as the argument register for `art_jni_lock_object` and passed as `obj`.
    lw      t2, THREAD_ID_OFFSET(xSELF)
    .if \can_be_null
        beqz    \obj, \slow_lock
    .endif
    addi    t1, \obj, MIRROR_OBJECT_LOCK_WORD_OFFSET  // Exclusive load/store has no offset.
1:
    // Note: The LR/SC sequence must be at most 16 instructions, so we cannot have the
    // recursive locking in a slow-path as on other architectures.
    lr.w.aq t3, (t1)                  // Acquire needed only in most common case.
    LUI_VALUE t5, LOCK_WORD_GC_STATE_MASK_SHIFTED  // Prepare mask for testing non-gc bits.
    xor     t4, t3, t2                // Prepare the value to store if unlocked
                                      //   (thread id, count of 0 and preserved read barrier bits),
                                      // or prepare to compare thread id for recursive lock check
                                      //   (lock_word.ThreadId() ^ self->ThreadId()).
    or      t6, t5, t3                // Test the non-gc bits.
    beq     t6, t5, 2f                // Check if unlocked.
                                      // Check lock word state and thread id together,
    LUI_VALUE \
        t5, 0xffffffff ^ (LOCK_WORD_STATE_MASK_SHIFTED | LOCK_WORD_THIN_LOCK_OWNER_MASK_SHIFTED)
    or      t6, t5, t4
    bne     t6, t5, \slow_lock
    LUI_VALUE t4, LOCK_WORD_THIN_LOCK_COUNT_ONE  // Increment the recursive lock count.
    addw    t4, t3, t4
    LUI_VALUE t5, LOCK_WORD_THIN_LOCK_COUNT_MASK_SHIFTED  // Test the new thin lock count.
    and     t5, t4, t5
    beqz    t5, \slow_lock            // Zero as the new count indicates overflow, go slow path.
2:
    // Store the prepared value:
    //   - if unlocked, original lock word plus thread id,
    //   - if already locked, original lock word plus incremented lock count.
    sc.w    t3, t4, (t1)
    bnez    t3, 1b                    // If the store failed, retry.
    ret
.endm

// Unlocking is needed for both managed code and JNI stubs.
.macro UNLOCK_OBJECT_FAST_PATH obj, slow_unlock, can_be_null
    // Use scratch registers T1-T6 as temporaries.
    // Note: T0 is used as the argument register for `art_jni_unlock_object` and passed as `obj`.
    lw      t2, THREAD_ID_OFFSET(xSELF)
    .if \can_be_null
        beqz    \obj, \slow_unlock
    .endif
    addi    t1, \obj, MIRROR_OBJECT_LOCK_WORD_OFFSET  // Exclusive load/store has no offset.
1:
    // Note: Without read barriers, we could do plain LW here but there is no store-release
    // other than SC on riscv64, so we do this with LR/SC for all cofigurations.
    // Note: The LR/SC sequence must be at most 16 instructions, so we cannot have the
    // recursive unlocking in a slow-path as on other architectures.
    lr.w    t3, (t1)
    LUI_VALUE t5, LOCK_WORD_GC_STATE_MASK_SHIFTED  // Prepare mask for testing non-gc bits.
    xor     t4, t3, t2                // Prepare the value to store if simply locked
                                      //   (mostly 0s, and preserved read barrier bits),
                                      // or prepare to compare thread id for recursive lock check
                                      //   (lock_word.ThreadId() ^ self->ThreadId()).
    or      t6, t5, t4                // Test the non-gc bits.
    beq     t6, t5, 2f                // Simply locked by this thread?
                                      // Check lock word state and thread id together.
    LUI_VALUE \
        t5, 0xffffffff ^ (LOCK_WORD_STATE_MASK_SHIFTED | LOCK_WORD_THIN_LOCK_OWNER_MASK_SHIFTED)
    or      t6, t5, t4
    bne     t6, t5, \slow_unlock
    LUI_VALUE t4, LOCK_WORD_THIN_LOCK_COUNT_ONE  // Decrement the recursive lock count.
    subw    t4, t3, t4
2:
    // Store the prepared value:
    //   - if simply locked, original lock word with removed thread id,
    //   - if recursively locked, original lock word plus decremented lock count.
    sc.w.rl t3, t4, (t1)              // Need to use atomic instructions for read barrier.
    bnez    t3, 1b                    // If the store failed, retry.
    ret
.endm


// Macros to branch based on the value of a specific bit.
.macro BRANCH_IF_BIT_CLEAR tmp, reg, bit, dest
    slli    \tmp, \reg, (63 - \bit) // tested bit => sign bit
    bgez    \tmp, \dest
.endm


.macro BRANCH_IF_BIT_SET tmp, reg, bit, dest
    slli    \tmp, \reg, (63 - \bit) // tested bit => sign bit
    bltz    \tmp, \dest
.endm


#endif  // ART_RUNTIME_ARCH_RISCV64_ASM_SUPPORT_RISCV64_S_

Messung V0.5 in Prozent
C=98 H=91 G=94

¤ Dauer der Verarbeitung: 0.24 Sekunden  (vorverarbeitet am  2026-06-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik