| /* |
| * 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. |
| */ |
| /** |
| * @author Intel, Evgueni Brevnov, Ivan Volosyuk |
| */ |
| |
| |
| #ifndef _M2N_IPF_INTERNAL_H_ |
| #define _M2N_IPF_INTERNAL_H_ |
| |
| // This file describes the internal IPF interface of m2n frames. |
| // It can be used by stubs to generate code to push and pop m2n frames and to update object handles fields. |
| // It is also used by stack iterators. |
| |
| #include "Code_Emitter.h" |
| #include "m2n.h" |
| #include "open/types.h" |
| |
| // Generate code to push an M2nFrame onto the stack |
| // The activation frame of the stub is used for the M2nFrame as are certain registers in this frame. |
| // The stub must preserve all preserved registers including pfs, gp, and b0 from entry to the stub to the time of push_m2n. |
| // The stub may use up to 8 inputs, the requested number of locals, and the requested number of outputs after push_m2n. |
| // method: the method to be associated with the M2nFrame or NULL for no association |
| // handles: does the stub want local handles or not |
| // num_on_stack: this number plus the current sp is the sp at entry to the stub (should be positive as stack grows down) |
| // num_local: the number of local registers above the M2N registers required by the stub |
| // num_outputs: the number of output registers required by the stub |
| // do_alloc: if false, the function should assume that the stacked register |
| // frame has been allocated, and no alloc instruction needs to be executed; it should also assume that ar.pfs is already saved at its proper place |
| // return: the register number for the first local, the outputs immediately follow the locals |
| // Note, the stub may use some of the 8 inputs as locals if it wants to |
| unsigned m2n_gen_push_m2n(Merced_Code_Emitter*, Method_Handle method, frame_type current_frame_type, bool handles, unsigned num_on_stack, unsigned num_locals, |
| unsigned num_outputs, bool do_alloc=true); |
| |
| enum M2nPreserveRet { MPR_None, MPR_Gr, MPR_Fr }; |
| |
| // Generate code to pop the M2nFrame from the stack. |
| // This should be matched by a preceeding push_m2n in the stub. |
| // handles: should match the push_m2n handles argument, if true the generated code will free the handles. |
| // preserve_ret_regs: the number of return registers to preserve (starting with r8). |
| // Note that the pop restores the callee saves gp registers, pfs, gp, and b0 to the values that had at the push m2n; it does not restore sp. |
| // do_alloc: must have the same value as the corresponding m2n_gen_push_m2n() parameter |
| // target: if handles==true and the vm property vm.free_local_object_handles |
| // is also true, m2n_gen_pop_m2n will need to set a target in the emitter; |
| // target will be the number used. Otherwise, this parameter is ignored. |
| // out_reg: if handles==true and the vm property vm.free_local_object_handles |
| // is also true, m2n_gen_pop_m2n needs to know the first output register; out_reg is this register. Otherwise this parameter is ignored |
| void m2n_gen_pop_m2n(Merced_Code_Emitter*, bool handles, M2nPreserveRet preserve_ret_regs, bool do_alloc=true, unsigned out_reg=0, int target=-1); |
| |
| // Generate code to set the local handles of the M2nFrame that is also the current frame. |
| // Preserves all registers that are not used to store M2nFrame information. |
| void m2n_gen_set_local_handles(Merced_Code_Emitter*, unsigned src_reg); |
| |
| // Generate code to set the local handles of the M2nFrame that is also the current frame. |
| // Preserves all registers that are not used to store M2nFrame information. |
| void m2n_gen_set_local_handles_imm(Merced_Code_Emitter*, uint64 imm_val); |
| |
| // Generate code to save additional preserved registers not normally saved by push_m2n. |
| // The combination of push_m2n and save_extra_preserved_registers will save all preserved registers as needed by exception propogation. |
| // The code generated by this function must follow that of push_m2n. |
| // Note that this function uses the memory stack, expects the scratch area above sp, and leaves a scratch area above sp. |
| void m2n_gen_save_extra_preserved_registers(Merced_Code_Emitter* emitter); |
| |
| |
| // returns the number of the last GR that the M2N frame uses |
| unsigned m2n_get_last_m2n_reg(); |
| |
| // the following functions return the GR numbers where various things should be saved |
| unsigned m2n_get_pfs_save_reg(); |
| unsigned m2n_get_return_save_reg(); |
| unsigned m2n_get_gp_save_reg(); |
| |
| // The IPF calling convention defines how to layout the arguments into words and then how to place |
| // these into gp registers, fp registers, or memory stack. This function returns a pointer to the |
| // nth word assuming it is either in a gp register or on the memory stack. |
| uint64* m2n_get_arg_word(M2nFrame*, unsigned n); |
| |
| ////////////////////////////////////////////////////////////////////////// |
| // Implementation details |
| |
| // An M2nFrame is always represented using the bsp value for register 32 of the frame |
| // The information needed for the frame is stored in stacked local registers or on the memory stack. |
| // It can be accessed by computing the spill location from the bsp value or by retrieving the sp value and |
| |
| uint64* m2n_get_bsp(M2nFrame*); |
| uint64* m2n_get_extra_saved(M2nFrame*); |
| |
| // Flushes register stack of the current thread into backing store and calls target procedure. |
| NativeCodePtr m2n_gen_flush_and_call(); |
| |
| // An M2nFrame will always have 8 input registers, some local stacked registers to save stuff, and some outputs |
| |
| #define M2N_NUMBER_ALIGNS 2 |
| #define M2N_NUMBER_INPUTS 8 |
| #define M2N_NUMBER_LOCALS 17 |
| |
| // The following registers are used in M2nFrames to hold the indicated values |
| // The register numbers must be distinct, at least 40 (so they don't conflict with inputs), and less than 40+M2N_NUMBER_LOCALS |
| |
| #define M2N_SAVED_PFS 40 |
| #define M2N_SAVED_RETURN_ADDRESS 41 |
| #define M2N_SAVED_M2NFL 42 |
| #define M2N_SAVED_SP 43 |
| #define M2N_SAVED_GP 44 |
| #define M2N_SAVED_PR 45 |
| #define M2N_SAVED_UNAT 46 |
| #define M2N_SAVED_R4 47 |
| #define M2N_SAVED_R5 48 |
| #define M2N_SAVED_R6 49 |
| #define M2N_SAVED_R7 50 |
| #define M2N_EXTRA_SAVED_PTR 51 |
| #define M2N_OBJECT_HANDLES 52 |
| #define M2N_METHOD 53 |
| #define M2N_FRAME_TYPE 54 |
| #define M2N_EXTRA_RNAT 55 |
| // this must be last register |
| #define M2N_EXTRA_UNAT 56 |
| |
| // Only the callee saves general registers are normally saved in the M2nFrame along with special things like pfs, return address, etc. |
| // The full set of preserved registers includes callee saves floating point and branch registers as well. |
| // These are saved, if requested, onto the memory stack as follows: |
| // +-------------------------+ |
| // | Saved f2 | |
| // Extra Saved ---> +-------------------------+ |
| // | Saved f3..f5 | |
| // +-------------------------+ |
| // | Saved f16..f31 | |
| // +-------------------------+ |
| // | Scratch area (8 bytes) | |
| // +-------------------------+ |
| // | Saved b1..b5 | |
| // +-------------------------+ |
| // | Saved ar.fpsr | |
| // +-------------------------+ |
| // | Saved ar.unat | |
| // +-------------------------+ |
| // | Saved ar.lc | |
| // +-------------------------+ |
| |
| #define M2N_EXTRA_SAVES_SPACE 400 |
| |
| #ifdef HYX86_64 |
| #error Should not be included! |
| #endif |
| |
| struct M2nFrame { |
| union { |
| uint64 buff[M2N_NUMBER_INPUTS + M2N_NUMBER_LOCALS + M2N_NUMBER_ALIGNS]; |
| struct { |
| M2nFrame* prev_m2nf; |
| ObjectHandles* local_object_handles; |
| Method_Handle method; |
| frame_type current_frame_type; // type of the current frame also shows is the frame unwindable |
| }; |
| }; |
| }; |
| |
| #endif //!_M2N_IPF_INTERNAL_H_ |