aboutsummaryrefslogblamecommitdiffstats
path: root/erts/emulator/beam/macros.tab
blob: 0d175a7ec647841c3b3735d2cacf659d7f4c5400 (plain) (tree)





























                                                                           








                                                                      
                   
                                          
                                  



                      
                                 


                        
                         


                               

                    
                      




                
                      




                          
                                         











                                                                            
                                         








                                                                              
                                   

























                                                                    




                        

                         






                                                            





















                                   
                             









                                                               
                             







                                                               
// -*- c -*-
//
// %CopyrightBegin%
//
// Copyright Ericsson AB 2017. All Rights Reserved.
//
// 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.
//
// %CopyrightEnd%
//

//
// Use if there is a garbage collection before storing to a
// general destination (either X or Y register).
//

REFRESH_GEN_DEST() {
    dst_ptr = REG_TARGET_PTR(dst);
}

// $Offset is relative to the start of the instruction (not to the
// location of the failure label reference). Since combined
// instructions may increment the instruction pointer (e.g. in
// 'increment') for some of the instructions in the group, we actually
// use a virtual start position common to all instructions in the
// group. To calculate the correct virtual position, we will need to
// add $IP_ADJUSTMENT to the offset. ($IP_ADJUSTMENT will usually be
// zero, except in a few bit syntax instructions.)

SET_I_REL(Offset) {
    ASSERT(VALID_INSTR(*(I + ($Offset))));
    I += $Offset + $IP_ADJUSTMENT;
}

SET_CP_I_ABS(Target) {
    c_p->i = $Target;
    ASSERT(VALID_INSTR(*c_p->i));
}

SET_REL_I(Dst, Offset) {
    $Dst = I + ($Offset);
    ASSERT(VALID_INSTR(*$Dst));
}

FAIL(Fail) {
    //| -no_prefetch
    $SET_I_REL($Fail);
    Goto(*I);
}

JUMP(Fail) {
    //| -no_next
    $SET_I_REL($Fail);
    Goto(*I);
}

GC_TEST(Ns, Nh, Live) {
    Uint need = $Nh + $Ns;
    if (ERTS_UNLIKELY(E - HTOP < need)) {
       SWAPOUT;
       PROCESS_MAIN_CHK_LOCKS(c_p);
       FCALLS -= erts_garbage_collect_nobump(c_p, need, reg, $Live, FCALLS);
       ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
       PROCESS_MAIN_CHK_LOCKS(c_p);
       SWAPIN;
    }
    HEAP_SPACE_VERIFIED($Nh);
}

GC_TEST_PRESERVE(NeedHeap, Live, PreserveTerm) {
    Uint need = $NeedHeap;
    if (ERTS_UNLIKELY(E - HTOP < need)) {
       SWAPOUT;
       reg[$Live] = $PreserveTerm;
       PROCESS_MAIN_CHK_LOCKS(c_p);
       FCALLS -= erts_garbage_collect_nobump(c_p, need, reg, $Live+1, FCALLS);
       ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
       PROCESS_MAIN_CHK_LOCKS(c_p);
       $PreserveTerm = reg[$Live];
       SWAPIN;
    }
    HEAP_SPACE_VERIFIED($NeedHeap);
}


// Make sure that there are NeedStack + NeedHeap + 1 words available
// on the combined heap/stack segment, then allocates NeedHeap + 1
// words on the stack and saves CP.
AH(NeedStack, NeedHeap, Live) {
    unsigned needed = $NeedStack + 1;
    $GC_TEST(needed, $NeedHeap, $Live);
    E -= needed;
    *E = make_cp(c_p->cp);
    c_p->cp = 0;
}

NEXT0() {
    //| -no_next
    SET_I((BeamInstr *) $NEXT_INSTRUCTION);
    Goto(*I);
}

NEXT(Addr) {
    //| -no_next
    SET_I((BeamInstr *) $Addr);
    Goto(*I);
}

FAIL_BODY() {
    //| -no_prefetch
    goto find_func_info;
}

FAIL_HEAD_OR_BODY(Fail) {
    //| -no_prefetch

    /*
     * In a correctly working program, we expect failures in
     * guards to be more likely than failures in bodies.
     */

    if (ERTS_LIKELY($Fail)) {
        $FAIL($Fail);
    }
    goto find_func_info;
}

BADARG(Fail) {
    c_p->freason = BADARG;
    $FAIL_HEAD_OR_BODY($Fail);
}

BADARITH0() {
    c_p->freason = BADARITH;
    goto find_func_info;
}

SYSTEM_LIMIT(Fail) {
    c_p->freason = SYSTEM_LIMIT;
    $FAIL_HEAD_OR_BODY($Fail);
}

BIF_ERROR_ARITY_1(Fail, BIF, Op1) {
    //| -no_prefetch
    if (ERTS_LIKELY($Fail)) {
        $FAIL($Fail);
    }
    reg[0] = $Op1;
    SWAPOUT;
    I = handle_error(c_p, I, reg, &bif_export[$BIF]->info.mfa);
    goto post_error_handling;
}

BIF_ERROR_ARITY_2(Fail, BIF, Op1, Op2) {
    //| -no_prefetch
    if (ERTS_LIKELY($Fail)) {
        $FAIL($Fail);
    }
    reg[0] = $Op1;
    reg[1] = $Op2;
    SWAPOUT;
    I = handle_error(c_p, I, reg, &bif_export[$BIF]->info.mfa);
    goto post_error_handling;
}