Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/cpu/aarch32/vm/c1_FrameMap_aarch32.cpp
32285 views
/*1* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2014, Red Hat Inc. All rights reserved.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/24// This file is a derivative work resulting from (and including) modifications25// made by Azul Systems, Inc. The dates of such changes are 2013-2016.26// Copyright 2013-2016 Azul Systems, Inc. All Rights Reserved.27//28// Please contact Azul Systems, 385 Moffett Park Drive, Suite 115, Sunnyvale,29// CA 94089 USA or visit www.azul.com if you need additional information or30// have any questions.3132#include "precompiled.hpp"33#include "c1/c1_FrameMap.hpp"34#include "c1/c1_LIR.hpp"35#include "runtime/sharedRuntime.hpp"36#include "vmreg_aarch32.inline.hpp"3738LIR_Opr FrameMap::r0_opr;39LIR_Opr FrameMap::r1_opr;40LIR_Opr FrameMap::r2_opr;41LIR_Opr FrameMap::r3_opr;42LIR_Opr FrameMap::r4_opr;43LIR_Opr FrameMap::r5_opr;44LIR_Opr FrameMap::r6_opr;45LIR_Opr FrameMap::r7_opr;46LIR_Opr FrameMap::r8_opr;47LIR_Opr FrameMap::r9_opr;48LIR_Opr FrameMap::r10_opr;49LIR_Opr FrameMap::r11_opr;50LIR_Opr FrameMap::r12_opr;51LIR_Opr FrameMap::r13_opr;52LIR_Opr FrameMap::r14_opr;53LIR_Opr FrameMap::r15_opr;5455LIR_Opr FrameMap::r0_oop_opr;56LIR_Opr FrameMap::r1_oop_opr;57LIR_Opr FrameMap::r2_oop_opr;58LIR_Opr FrameMap::r3_oop_opr;59LIR_Opr FrameMap::r4_oop_opr;60LIR_Opr FrameMap::r5_oop_opr;61LIR_Opr FrameMap::r6_oop_opr;62LIR_Opr FrameMap::r7_oop_opr;63LIR_Opr FrameMap::r8_oop_opr;64LIR_Opr FrameMap::r9_oop_opr;65LIR_Opr FrameMap::r10_oop_opr;66LIR_Opr FrameMap::r11_oop_opr;67LIR_Opr FrameMap::r12_oop_opr;68LIR_Opr FrameMap::r13_oop_opr;69LIR_Opr FrameMap::r14_oop_opr;70LIR_Opr FrameMap::r15_oop_opr;7172LIR_Opr FrameMap::r0_metadata_opr;73LIR_Opr FrameMap::r1_metadata_opr;74LIR_Opr FrameMap::r2_metadata_opr;75LIR_Opr FrameMap::r3_metadata_opr;76LIR_Opr FrameMap::r4_metadata_opr;77LIR_Opr FrameMap::r5_metadata_opr;7879LIR_Opr FrameMap::sp_opr;80LIR_Opr FrameMap::receiver_opr;8182LIR_Opr FrameMap::rscratch1_opr;83LIR_Opr FrameMap::rscratch2_opr;84LIR_Opr FrameMap::rscratch_long_opr;8586LIR_Opr FrameMap::long0_opr;87LIR_Opr FrameMap::long1_opr;88LIR_Opr FrameMap::long2_opr;89LIR_Opr FrameMap::fpu0_float_opr;90LIR_Opr FrameMap::fpu0_double_opr;9192LIR_Opr FrameMap::_caller_save_cpu_regs[] = { 0, };93LIR_Opr FrameMap::_caller_save_fpu_regs[] = { 0, };9495void FrameMap::initialize() {96assert(!_init_done, "must be called once");9798int i = 0;99map_register(i, r0); r0_opr = LIR_OprFact::single_cpu(i); i++;100map_register(i, r1); r1_opr = LIR_OprFact::single_cpu(i); i++;101map_register(i, r2); r2_opr = LIR_OprFact::single_cpu(i); i++;102map_register(i, r3); r3_opr = LIR_OprFact::single_cpu(i); i++;103map_register(i, r4); r4_opr = LIR_OprFact::single_cpu(i); i++;104map_register(i, r5); r5_opr = LIR_OprFact::single_cpu(i); i++;105map_register(i, r6); r6_opr = LIR_OprFact::single_cpu(i); i++;106map_register(i, r7); r7_opr = LIR_OprFact::single_cpu(i); i++;107// Mapping lines in this block may be arbitrarily mixed, but all allocatable108// registers should go above this comment, and unallocatable registers -109// below.110map_register(i, r8); r8_opr = LIR_OprFact::single_cpu(i); i++; // rthread111map_register(i, r9); r9_opr = LIR_OprFact::single_cpu(i); i++; // rscratch1112map_register(i, r10); r10_opr = LIR_OprFact::single_cpu(i); i++; // rmethod113map_register(i, r11); r11_opr = LIR_OprFact::single_cpu(i); i++; // rfp114map_register(i, r12); r12_opr = LIR_OprFact::single_cpu(i); i++; // rscratch2115map_register(i, r13); r13_opr = LIR_OprFact::single_cpu(i); i++; // sp116map_register(i, r14); r14_opr = LIR_OprFact::single_cpu(i); i++; // lr117map_register(i, r15); r15_opr = LIR_OprFact::single_cpu(i); i++; // r15_pc118119// This flag must be set after all integer registers are mapped but before120// the first use of as_*_opr() methods.121_init_done = true;122123r0_oop_opr = as_oop_opr(r0);124r1_oop_opr = as_oop_opr(r1);125r2_oop_opr = as_oop_opr(r2);126r3_oop_opr = as_oop_opr(r3);127r4_oop_opr = as_oop_opr(r4);128r5_oop_opr = as_oop_opr(r5);129r6_oop_opr = as_oop_opr(r6);130r7_oop_opr = as_oop_opr(r7);131r8_oop_opr = as_oop_opr(r8);132r9_oop_opr = as_oop_opr(r9);133r10_oop_opr = as_oop_opr(r10);134r11_oop_opr = as_oop_opr(r11);135r12_oop_opr = as_oop_opr(r12);136r13_oop_opr = as_oop_opr(r13);137r14_oop_opr = as_oop_opr(r14);138r15_oop_opr = as_oop_opr(r15);139140r0_metadata_opr = as_metadata_opr(r0);141r1_metadata_opr = as_metadata_opr(r1);142r2_metadata_opr = as_metadata_opr(r2);143r3_metadata_opr = as_metadata_opr(r3);144r4_metadata_opr = as_metadata_opr(r4);145r5_metadata_opr = as_metadata_opr(r5);146147sp_opr = as_pointer_opr(sp);148149VMRegPair regs;150BasicType sig_bt = T_OBJECT;151SharedRuntime::java_calling_convention(&sig_bt, ®s, 1, true);152receiver_opr = as_oop_opr(regs.first()->as_Register());153154rscratch1_opr = as_opr(rscratch1);155rscratch2_opr = as_opr(rscratch2);156rscratch_long_opr = as_long_opr(rscratch1, rscratch2);157158long0_opr = as_long_opr(r0, r1);159long1_opr = as_long_opr(r2, r3);160long2_opr = as_long_opr(r4, r5);161fpu0_float_opr = LIR_OprFact::single_fpu(0);162fpu0_double_opr = LIR_OprFact::double_fpu(0, 1);163164_caller_save_cpu_regs[0] = r0_opr;165_caller_save_cpu_regs[1] = r1_opr;166_caller_save_cpu_regs[2] = r2_opr;167_caller_save_cpu_regs[3] = r3_opr;168_caller_save_cpu_regs[4] = r4_opr;169_caller_save_cpu_regs[5] = r5_opr;170_caller_save_cpu_regs[6] = r6_opr;171_caller_save_cpu_regs[7] = r7_opr;172173for (i = 0; i < nof_caller_save_fpu_regs; i++) {174_caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i);175}176}177178LIR_Opr FrameMap::stack_pointer() {179return sp_opr;180}181182// TODO: Make sure that neither method handle intrinsics nor compiled lambda183// forms modify sp register (i.e., vmIntrinsics::{_invokeBasic, _linkToVirtual,184// _linkToStatic, _linkToSpecial, _linkToInterface, _compiledLambdaForm})185LIR_Opr FrameMap::method_handle_invoke_SP_save_opr() {186return LIR_OprFact::illegalOpr;187}188189// Return LIR_Opr corresponding to the given VMRegPair and data type190LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool) {191LIR_Opr opr = LIR_OprFact::illegalOpr;192VMReg r_1 = reg->first();193VMReg r_2 = reg->second();194if (r_1->is_stack()) {195// Convert stack slot to sp-based address. The calling convention does not196// count the SharedRuntime::out_preserve_stack_slots() value, so we must197// add it in here.198int st_off =199(r_1->reg2stack() + SharedRuntime::out_preserve_stack_slots()) *200VMRegImpl::stack_slot_size;201opr = LIR_OprFact::address(new LIR_Address(sp_opr, st_off, type));202} else if (r_1->is_Register()) {203Register reg1 = r_1->as_Register();204#ifdef HARD_FLOAT_CC205if (type == T_DOUBLE || type == T_FLOAT) {206ShouldNotReachHere();207} else208#endif209if (type == T_LONG || type == T_DOUBLE) {210assert(r_2->is_Register(), "wrong VMReg");211Register reg2 = r_2->as_Register();212opr = as_long_opr(reg1, reg2);213} else if (type == T_OBJECT || type == T_ARRAY) {214opr = as_oop_opr(reg1);215} else if (type == T_METADATA) {216opr = as_metadata_opr(reg1);217} else {218opr = as_opr(reg1);219}220} else if (r_1->is_FloatRegister()) {221int num = r_1->as_FloatRegister()->encoding();222if (type == T_FLOAT) {223opr = LIR_OprFact::single_fpu(num);224} else {225assert(is_even(num) && r_2->as_FloatRegister()->encoding() == (num + 1),226"wrong VMReg");227opr = LIR_OprFact::double_fpu(num, num + 1);228}229} else {230ShouldNotReachHere();231}232return opr;233}234235// Return VMReg corresponding to the given FPU register number as it is236// encoded in LIR_Opr. The conversion is straightforward because in this237// implementation the encoding of FPU registers in LIR_Opr's is the same as238// in FloatRegister's.239VMReg FrameMap::fpu_regname(int n) {240return as_FloatRegister(n)->as_VMReg();241}242243// Check that the frame is properly addressable on the platform. The sp-based244// address of every frame slot must have the offset expressible as AArch32's245// imm12 with the separately stored sign.246bool FrameMap::validate_frame() {247int max_offset = in_bytes(framesize_in_bytes());248int java_index = 0;249for (int i = 0; i < _incoming_arguments->length(); i++) {250LIR_Opr opr = _incoming_arguments->at(i);251if (opr->is_stack()) {252max_offset = MAX2(_argument_locations->at(java_index), max_offset);253}254java_index += type2size[opr->type()];255}256return Assembler::is_valid_for_offset_imm(max_offset, 12);257}258259Address FrameMap::make_new_address(ByteSize sp_offset) const {260return Address(sp, in_bytes(sp_offset));261}262263264