src/cpu/mips/vm/runtime_mips_64.cpp

Tue, 26 Jul 2016 17:06:17 +0800

author
fujie
date
Tue, 26 Jul 2016 17:06:17 +0800
changeset 41
d885f8d65c58
parent 1
2d8a650513c2
child 368
11ec15adb6c4
permissions
-rw-r--r--

Add multiply word to GPR instruction (mul) in MIPS assembler.

aoqi@1 1 /*
aoqi@1 2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
aoqi@1 3 * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
aoqi@1 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@1 5 *
aoqi@1 6 * This code is free software; you can redistribute it and/or modify it
aoqi@1 7 * under the terms of the GNU General Public License version 2 only, as
aoqi@1 8 * published by the Free Software Foundation.
aoqi@1 9 *
aoqi@1 10 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@1 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@1 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@1 13 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@1 14 * accompanied this code).
aoqi@1 15 *
aoqi@1 16 * You should have received a copy of the GNU General Public License version
aoqi@1 17 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@1 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@1 19 *
aoqi@1 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@1 21 * or visit www.oracle.com if you need additional information or have any
aoqi@1 22 * questions.
aoqi@1 23 *
aoqi@1 24 */
aoqi@1 25
aoqi@1 26 #include "precompiled.hpp"
aoqi@1 27 #ifdef COMPILER2
aoqi@1 28 #include "asm/macroAssembler.hpp"
aoqi@1 29 #include "asm/macroAssembler.inline.hpp"
aoqi@1 30 #include "classfile/systemDictionary.hpp"
aoqi@1 31 #include "code/vmreg.hpp"
aoqi@1 32 #include "interpreter/interpreter.hpp"
aoqi@1 33 #include "opto/runtime.hpp"
aoqi@1 34 #include "runtime/interfaceSupport.hpp"
aoqi@1 35 #include "runtime/sharedRuntime.hpp"
aoqi@1 36 #include "runtime/stubRoutines.hpp"
aoqi@1 37 #include "runtime/vframeArray.hpp"
aoqi@1 38 #include "utilities/globalDefinitions.hpp"
aoqi@1 39 #include "vmreg_mips.inline.hpp"
aoqi@1 40 #endif
aoqi@1 41
aoqi@1 42 #define __ masm->
aoqi@1 43
aoqi@1 44 //-------------- generate_exception_blob -----------
aoqi@1 45 // creates _exception_blob.
aoqi@1 46 // The exception blob is jumped to from a compiled method.
aoqi@1 47 // (see emit_exception_handler in sparc.ad file)
aoqi@1 48 //
aoqi@1 49 // Given an exception pc at a call we call into the runtime for the
aoqi@1 50 // handler in this method. This handler might merely restore state
aoqi@1 51 // (i.e. callee save registers) unwind the frame and jump to the
aoqi@1 52 // exception handler for the nmethod if there is no Java level handler
aoqi@1 53 // for the nmethod.
aoqi@1 54 //
aoqi@1 55 // This code is entered with a jump, and left with a jump.
aoqi@1 56 //
aoqi@1 57 // Arguments:
aoqi@1 58 // V0: exception oop
aoqi@1 59 // V1: exception pc
aoqi@1 60 //
aoqi@1 61 // Results:
aoqi@1 62 // A0: exception oop
aoqi@1 63 // A1: exception pc in caller or ???
aoqi@1 64 // jumps to: exception handler of caller
aoqi@1 65 //
aoqi@1 66 // Note: the exception pc MUST be at a call (precise debug information)
aoqi@1 67 //
aoqi@1 68 // 2012/9/14 Jin: [stubGenerator_mips.cpp] generate_forward_exception()
aoqi@1 69 // |- V0, V1 are created
aoqi@1 70 // |- T9 <= SharedRuntime::exception_handler_for_return_address
aoqi@1 71 // `- jr T9
aoqi@1 72 // `- the caller's exception_handler
aoqi@1 73 // `- jr OptoRuntime::exception_blob
aoqi@1 74 // `- here
aoqi@1 75 //
aoqi@1 76 void OptoRuntime::generate_exception_blob() {
aoqi@1 77 // Capture info about frame layout
aoqi@1 78 enum layout {
aoqi@1 79 fp_off,
aoqi@1 80 return_off, // slot for return address
aoqi@1 81 framesize
aoqi@1 82 };
aoqi@1 83
aoqi@1 84 // allocate space for the code
aoqi@1 85 ResourceMark rm;
aoqi@1 86 // setup code generation tools
aoqi@1 87 CodeBuffer buffer("exception_blob", 5120, 5120);
aoqi@1 88 MacroAssembler* masm = new MacroAssembler(&buffer);
aoqi@1 89
aoqi@1 90 // OopMapSet *oop_maps = new OopMapSet();
aoqi@1 91
aoqi@1 92 address start = __ pc();
aoqi@1 93
aoqi@1 94 __ daddiu(SP, SP, -1 * framesize * wordSize); // Prolog!
aoqi@1 95
aoqi@1 96 /* 2012/9.27 Jin: this frame will be treated as the original caller method.
aoqi@1 97 * So, the return pc should be filled with the original exception pc.
aoqi@1 98 * ref: X86's implementation
aoqi@1 99 */
aoqi@1 100 __ sd(V1, SP, return_off *wordSize); // return address
aoqi@1 101 __ sd(FP, SP, fp_off *wordSize); // EBP
aoqi@1 102
aoqi@1 103 // Save callee saved registers. None for UseSSE=0,
aoqi@1 104 // floats-only for UseSSE=1, and doubles for UseSSE=2.
aoqi@1 105
aoqi@1 106 __ daddiu(FP, SP, fp_off * wordSize);
aoqi@1 107
aoqi@1 108 // Store exception in Thread object. We cannot pass any arguments to the
aoqi@1 109 // handle_exception call, since we do not want to make any assumption
aoqi@1 110 // about the size of the frame where the exception happened in.
aoqi@1 111 Register thread = TREG;
aoqi@1 112
aoqi@1 113 #ifndef OPT_THREAD
aoqi@1 114 __ get_thread(thread);
aoqi@1 115 #endif
aoqi@1 116
aoqi@1 117 __ sd(V0, Address(thread, JavaThread::exception_oop_offset()));
aoqi@1 118 __ sd(V1, Address(thread, JavaThread::exception_pc_offset()));
aoqi@1 119
aoqi@1 120 // This call does all the hard work. It checks if an exception handler
aoqi@1 121 // exists in the method.
aoqi@1 122 // If so, it returns the handler address.
aoqi@1 123 // If not, it prepares for stack-unwinding, restoring the callee-save
aoqi@1 124 // registers of the frame being removed.
aoqi@1 125 __ set_last_Java_frame(thread, NOREG, NOREG, NULL);
aoqi@1 126
aoqi@1 127 __ move(AT, -(StackAlignmentInBytes));
aoqi@1 128 __ andr(SP, SP, AT); // Fix stack alignment as required by ABI
aoqi@1 129
aoqi@1 130 __ relocate(relocInfo::internal_pc_type);
aoqi@1 131
aoqi@1 132 {
aoqi@1 133 long save_pc = (long)__ pc() + 24 + NativeCall::return_address_offset;
aoqi@1 134 __ li48(AT, save_pc);
aoqi@1 135 }
aoqi@1 136 __ sd(AT, thread, in_bytes(JavaThread::last_Java_pc_offset()));
aoqi@1 137
aoqi@1 138 __ move(A0, thread);
aoqi@1 139 __ li48(T9, (long)OptoRuntime::handle_exception_C);
aoqi@1 140 __ jalr(T9);
aoqi@1 141 __ delayed()->nop();
aoqi@1 142
aoqi@1 143 // Set an oopmap for the call site
aoqi@1 144 OopMapSet *oop_maps = new OopMapSet();
aoqi@1 145 OopMap* map = new OopMap( framesize, 0 );
aoqi@1 146
aoqi@1 147 oop_maps->add_gc_map( __ offset(), map);
aoqi@1 148
aoqi@1 149 #ifndef OPT_THREAD
aoqi@1 150 __ get_thread(thread);
aoqi@1 151 #endif
aoqi@1 152 __ reset_last_Java_frame(thread, true, true);
aoqi@1 153
aoqi@1 154 // Pop self-frame.
aoqi@1 155 __ leave(); // Epilog!
aoqi@1 156
aoqi@1 157 // rax,: exception handler for given <exception oop/exception pc>
aoqi@1 158
aoqi@1 159 // We have a handler in rax, (could be deopt blob)
aoqi@1 160 // rdx - throwing pc, deopt blob will need it.
aoqi@1 161 /* FIXME: rdx? */
aoqi@1 162
aoqi@1 163 // rcx contains handler address
aoqi@1 164 __ move(T9, V0);
aoqi@1 165
aoqi@1 166 #ifndef OPT_THREAD
aoqi@1 167 __ get_thread(thread);
aoqi@1 168 #endif
aoqi@1 169 // Get the exception
aoqi@1 170 __ ld(A0, Address(thread, JavaThread::exception_oop_offset()));
aoqi@1 171 // Get the exception pc in case we are deoptimized
aoqi@1 172 __ ld(A1, Address(thread, JavaThread::exception_pc_offset()));
aoqi@1 173 #ifdef ASSERT
aoqi@1 174 __ sd(R0, Address(thread, JavaThread::exception_handler_pc_offset()));
aoqi@1 175 __ sd(R0, Address(thread, JavaThread::exception_pc_offset()));
aoqi@1 176 #endif
aoqi@1 177 // Clear the exception oop so GC no longer processes it as a root.
aoqi@1 178 __ sd(R0, Address(thread, JavaThread::exception_oop_offset()));
aoqi@1 179
aoqi@1 180 /* 2014/5/12 Jin: Fix seg fault when running:
aoqi@1 181 * Eclipse + Plugin + Debug As
aoqi@1 182 * This is the only condition where C2 calls SharedRuntime::generate_deopt_blob()
aoqi@1 183 *
aoqi@1 184 * Ref: http://10.2.5.21:8000/projects/java/wiki/Jgj-log-2014-5-12_
aoqi@1 185 */
aoqi@1 186 __ move(V0, A0);
aoqi@1 187 __ move(V1, A1);
aoqi@1 188
aoqi@1 189 // rax,: exception oop
aoqi@1 190 // rcx: exception handler
aoqi@1 191 // rdx: exception pc
aoqi@1 192 __ jr(T9);
aoqi@1 193 __ delayed()->nop();
aoqi@1 194
aoqi@1 195 // make sure all code is generated
aoqi@1 196 masm->flush();
aoqi@1 197
aoqi@1 198 _exception_blob = ExceptionBlob::create(&buffer, oop_maps, framesize);
aoqi@1 199 }

mercurial