1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/mips/vm/c1_LIRAssembler_mips.cpp Fri Apr 29 00:06:10 2016 +0800 1.3 @@ -0,0 +1,5345 @@ 1.4 +/* 1.5 + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved. 1.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 + * 1.9 + * This code is free software; you can redistribute it and/or modify it 1.10 + * under the terms of the GNU General Public License version 2 only, as 1.11 + * published by the Free Software Foundation. 1.12 + * 1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.16 + * version 2 for more details (a copy is included in the LICENSE file that 1.17 + * accompanied this code). 1.18 + * 1.19 + * You should have received a copy of the GNU General Public License version 1.20 + * 2 along with this work; if not, write to the Free Software Foundation, 1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.22 + * 1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.24 + * or visit www.oracle.com if you need additional information or have any 1.25 + * questions. 1.26 + * 1.27 + */ 1.28 + 1.29 +#include "precompiled.hpp" 1.30 +#include "asm/macroAssembler.hpp" 1.31 +#include "asm/macroAssembler.inline.hpp" 1.32 +#include "c1/c1_Compilation.hpp" 1.33 +#include "c1/c1_LIRAssembler.hpp" 1.34 +#include "c1/c1_MacroAssembler.hpp" 1.35 +#include "c1/c1_Runtime1.hpp" 1.36 +#include "c1/c1_ValueStack.hpp" 1.37 +#include "ci/ciArrayKlass.hpp" 1.38 +#include "ci/ciInstance.hpp" 1.39 +#include "gc_interface/collectedHeap.hpp" 1.40 +#include "memory/barrierSet.hpp" 1.41 +#include "memory/cardTableModRefBS.hpp" 1.42 +#include "nativeInst_mips.hpp" 1.43 +#include "oops/objArrayKlass.hpp" 1.44 +#include "runtime/sharedRuntime.hpp" 1.45 +#define __ _masm-> 1.46 + 1.47 +static void select_different_registers(Register preserve, 1.48 + Register extra, 1.49 + Register &tmp1, 1.50 + Register &tmp2) { 1.51 + if (tmp1 == preserve) { 1.52 + assert_different_registers(tmp1, tmp2, extra); 1.53 + tmp1 = extra; 1.54 + } else if (tmp2 == preserve) { 1.55 + assert_different_registers(tmp1, tmp2, extra); 1.56 + tmp2 = extra; 1.57 + } 1.58 + assert_different_registers(preserve, tmp1, tmp2); 1.59 +} 1.60 + 1.61 + 1.62 + 1.63 +static void select_different_registers(Register preserve, 1.64 + Register extra, 1.65 + Register &tmp1, 1.66 + Register &tmp2, 1.67 + Register &tmp3) { 1.68 + if (tmp1 == preserve) { 1.69 + assert_different_registers(tmp1, tmp2, tmp3, extra); 1.70 + tmp1 = extra; 1.71 + } else if (tmp2 == preserve) { 1.72 + tmp2 = extra; 1.73 + } else if (tmp3 == preserve) { 1.74 + assert_different_registers(tmp1, tmp2, tmp3, extra); 1.75 + tmp3 = extra; 1.76 + } 1.77 + assert_different_registers(preserve, tmp1, tmp2, tmp3); 1.78 +} 1.79 + 1.80 +// need add method Assembler::is_simm16 in assembler_gs2.hpp 1.81 +bool LIR_Assembler::is_small_constant(LIR_Opr opr) { 1.82 + if (opr->is_constant()) { 1.83 + LIR_Const* constant = opr->as_constant_ptr(); 1.84 + switch (constant->type()) { 1.85 + case T_INT: { 1.86 + jint value = constant->as_jint(); 1.87 + return Assembler::is_simm16(value); 1.88 + } 1.89 + default: 1.90 + return false; 1.91 + } 1.92 + } 1.93 + return false; 1.94 +} 1.95 + 1.96 +//FIXME, which register should be used? 1.97 +LIR_Opr LIR_Assembler::receiverOpr() { 1.98 + return FrameMap::_t0_oop_opr; 1.99 +} 1.100 +/* 1.101 +LIR_Opr LIR_Assembler::incomingReceiverOpr() { 1.102 + return receiverOpr(); 1.103 +}*/ 1.104 + 1.105 +LIR_Opr LIR_Assembler::osrBufferPointer() { 1.106 +#ifdef _LP64 1.107 + Register r = receiverOpr()->as_register(); 1.108 + return FrameMap::as_long_opr(r, r); 1.109 +#else 1.110 + return FrameMap::as_opr(receiverOpr()->as_register()); 1.111 +#endif 1.112 +} 1.113 + 1.114 +//--------------fpu register translations----------------------- 1.115 +// FIXME:I do not know what's to do for mips fpu 1.116 + 1.117 +address LIR_Assembler::float_constant(float f) { 1.118 + address const_addr = __ float_constant(f); 1.119 + if (const_addr == NULL) { 1.120 + bailout("const section overflow"); 1.121 + return __ code()->consts()->start(); 1.122 + } else { 1.123 + return const_addr; 1.124 + } 1.125 +} 1.126 + 1.127 + 1.128 +address LIR_Assembler::double_constant(double d) { 1.129 + address const_addr = __ double_constant(d); 1.130 + if (const_addr == NULL) { 1.131 + bailout("const section overflow"); 1.132 + return __ code()->consts()->start(); 1.133 + } else { 1.134 + return const_addr; 1.135 + } 1.136 +} 1.137 + 1.138 + 1.139 + 1.140 + 1.141 + 1.142 +void LIR_Assembler::reset_FPU() { 1.143 + Unimplemented(); 1.144 +} 1.145 + 1.146 + 1.147 +void LIR_Assembler::set_24bit_FPU() { 1.148 + Unimplemented(); 1.149 +} 1.150 + 1.151 +//FIXME. 1.152 +void LIR_Assembler::fpop() { 1.153 + // do nothing 1.154 +} 1.155 +void LIR_Assembler::fxch(int i) { 1.156 + // do nothing 1.157 +} 1.158 +void LIR_Assembler::fld(int i) { 1.159 + // do nothing 1.160 +} 1.161 +void LIR_Assembler::ffree(int i) { 1.162 + // do nothing 1.163 +} 1.164 + 1.165 +void LIR_Assembler::breakpoint() { 1.166 + __ brk(17); 1.167 +} 1.168 +//FIXME, opr can not be float? 1.169 +void LIR_Assembler::push(LIR_Opr opr) { 1.170 + if (opr->is_single_cpu()) { 1.171 + __ push_reg(opr->as_register()); 1.172 + } else if (opr->is_double_cpu()) { 1.173 + __ push_reg(opr->as_register_hi()); 1.174 + __ push_reg(opr->as_register_lo()); 1.175 + } else if (opr->is_stack()) { 1.176 + __ push_addr(frame_map()->address_for_slot(opr->single_stack_ix())); 1.177 + } else if (opr->is_constant()) { 1.178 + LIR_Const* const_opr = opr->as_constant_ptr(); 1.179 + if (const_opr->type() == T_OBJECT) { 1.180 + __ push_oop(const_opr->as_jobject()); 1.181 + } else if (const_opr->type() == T_INT) { 1.182 + __ push_jint(const_opr->as_jint()); 1.183 + } else { 1.184 + ShouldNotReachHere(); 1.185 + } 1.186 + } else { 1.187 + ShouldNotReachHere(); 1.188 + } 1.189 +} 1.190 + 1.191 +void LIR_Assembler::pop(LIR_Opr opr) { 1.192 + if (opr->is_single_cpu() ) { 1.193 + __ pop(opr->as_register()); 1.194 + } else { 1.195 + assert(false, "Must be single word register or floating-point register"); 1.196 + } 1.197 +} 1.198 + 1.199 + 1.200 +Address LIR_Assembler::as_Address(LIR_Address* addr) { 1.201 +#ifndef _LP64 1.202 + Register reg = addr->base()->as_register(); 1.203 +#else 1.204 +//FIXME aoqi 1.205 + Register reg = addr->base()->is_single_cpu()? addr->base()->as_register() : addr->base()->as_register_lo(); 1.206 +#endif 1.207 + // now we need this for parameter pass 1.208 + return Address(reg, addr->disp()); 1.209 +} 1.210 + 1.211 + 1.212 +Address LIR_Assembler::as_Address_lo(LIR_Address* addr) { 1.213 + return as_Address(addr); 1.214 +} 1.215 + 1.216 + 1.217 +Address LIR_Assembler::as_Address_hi(LIR_Address* addr) { 1.218 + Register reg = addr->base()->as_register(); 1.219 + return Address(reg, addr->disp()+longSize/2); 1.220 +} 1.221 + 1.222 + 1.223 +//void LIR_Assembler::osr_entry(IRScope* scope, int number_of_locks, Label* continuation, int osr_bci) { 1.224 +void LIR_Assembler::osr_entry() { 1.225 + // assert(scope->is_top_scope(), "inlined OSR not yet implemented"); 1.226 + offsets()->set_value(CodeOffsets::OSR_Entry, code_offset()); 1.227 + BlockBegin* osr_entry = compilation()->hir()->osr_entry(); 1.228 + ValueStack* entry_state = osr_entry->state(); 1.229 + int number_of_locks = entry_state->locks_size(); 1.230 + 1.231 + // we jump here if osr happens with the interpreter 1.232 + // state set up to continue at the beginning of the 1.233 + // loop that triggered osr - in particular, we have 1.234 + // the following registers setup: 1.235 + // 1.236 + // S7: interpreter locals pointer 1.237 + // V1: interpreter locks pointer 1.238 + // RA: return address 1.239 + //T0: OSR buffer 1.240 + // build frame 1.241 + // ciMethod* m = scope->method(); 1.242 + ciMethod* m = compilation()->method(); 1.243 + __ build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes()); 1.244 + 1.245 + // OSR buffer is 1.246 + // 1.247 + // locals[nlocals-1..0] 1.248 + // monitors[0..number_of_locks] 1.249 + // 1.250 + // locals is a direct copy of the interpreter frame so in the osr buffer 1.251 + // so first slot in the local array is the last local from the interpreter 1.252 + // and last slot is local[0] (receiver) from the interpreter 1.253 + // 1.254 + // Similarly with locks. The first lock slot in the osr buffer is the nth lock 1.255 + // from the interpreter frame, the nth lock slot in the osr buffer is 0th lock 1.256 + // in the interpreter frame (the method lock if a sync method) 1.257 + 1.258 + // Initialize monitors in the compiled activation. 1.259 + // T0: pointer to osr buffer 1.260 + // 1.261 + // All other registers are dead at this point and the locals will be 1.262 + // copied into place by code emitted in the IR. 1.263 + 1.264 + Register OSR_buf = osrBufferPointer()->as_pointer_register(); 1.265 + 1.266 + 1.267 + // note: we do osr only if the expression stack at the loop beginning is empty, 1.268 + // in which case the spill area is empty too and we don't have to setup 1.269 + // spilled locals 1.270 + // 1.271 + // copy monitors 1.272 + // V1: pointer to locks 1.273 + { 1.274 + assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below"); 1.275 + int monitor_offset = BytesPerWord * method()->max_locals()+ 1.276 + (BasicObjectLock::size() * BytesPerWord) * (number_of_locks - 1); 1.277 + for (int i = 0; i < number_of_locks; i++) { 1.278 + int slot_offset =monitor_offset - (i * BasicObjectLock::size())*BytesPerWord; 1.279 +#ifdef ASSERT 1.280 + { 1.281 + Label L; 1.282 + //__ lw(AT, V1, slot_offset * BytesPerWord + BasicObjectLock::obj_offset_in_bytes()); 1.283 + __ ld_ptr(AT, OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes()); 1.284 + __ bne(AT, R0, L); 1.285 + __ delayed()->nop(); 1.286 + __ stop("locked object is NULL"); 1.287 + __ bind(L); 1.288 + } 1.289 +#endif 1.290 + __ ld_ptr(AT, OSR_buf, slot_offset + BasicObjectLock::lock_offset_in_bytes()); 1.291 + __ st_ptr(AT, frame_map()->address_for_monitor_lock(i)); 1.292 + __ ld_ptr(AT, OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes()); 1.293 + __ st_ptr(AT, frame_map()->address_for_monitor_object(i)); 1.294 + } 1.295 + } 1.296 +} 1.297 + 1.298 + 1.299 +int LIR_Assembler::check_icache() { 1.300 + Register receiver = FrameMap::receiver_opr->as_register(); 1.301 + Register ic_klass = IC_Klass; 1.302 + 1.303 + /*const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); 1.304 + const bool do_post_padding = VerifyOops || UseCompressedOops; 1.305 + if (!do_post_padding) { 1.306 + // insert some nops so that the verified entry point is aligned on CodeEntryAlignment 1.307 + while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) { 1.308 + __ nop(); 1.309 + } 1.310 + }*/ 1.311 + 1.312 + int offset = __ offset(); 1.313 + __ inline_cache_check(receiver, IC_Klass); 1.314 + __ align(CodeEntryAlignment); 1.315 + return offset; 1.316 + 1.317 + 1.318 +} 1.319 + 1.320 +void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo* info) { 1.321 + jobject o = NULL; 1.322 + PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_klass_id); 1.323 + int oop_index = __ oop_recorder()->allocate_oop_index(o); 1.324 + RelocationHolder rspec = oop_Relocation::spec(oop_index); 1.325 + __ relocate(rspec); 1.326 +#ifndef _LP64 1.327 +//by_css 1.328 + __ lui(reg, Assembler::split_high((int)o)); 1.329 + __ addiu(reg, reg, Assembler::split_low((int)o)); 1.330 +#else 1.331 +//li may not pass NativeMovConstReg::verify. see nativeMovConstReg_at(pc_start()); in PatchingStub::install. by aoqi 1.332 + __ li48(reg, (long)o); 1.333 +#endif 1.334 + // patching_epilog(patch, LIR_Op1::patch_normal, noreg, info); 1.335 + patching_epilog(patch, lir_patch_normal, reg, info); 1.336 +} 1.337 + 1.338 + 1.339 +void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register unused, int monitor_no, Register exception) { 1.340 + 1.341 + if (exception->is_valid()) { 1.342 + // preserve exception 1.343 + // note: the monitor_exit runtime call is a leaf routine 1.344 + // and cannot block => no GC can happen 1.345 + // The slow case (MonitorAccessStub) uses the first two stack slots 1.346 + // ([SP+0] and [SP+4]), therefore we store the exception at [esp+8] 1.347 + __ st_ptr(exception, SP, 2 * wordSize); 1.348 + } 1.349 + 1.350 + Register obj_reg = obj_opr->as_register(); 1.351 + Register lock_reg = lock_opr->as_register(); 1.352 + 1.353 + // compute pointer to BasicLock 1.354 + //Address lock_addr = frame_map()->address_for_monitor_lock_index(monitor_no); 1.355 + Address lock_addr = frame_map()->address_for_monitor_lock(monitor_no); 1.356 + __ lea(lock_reg, lock_addr); 1.357 + // unlock object 1.358 + MonitorAccessStub* slow_case = new MonitorExitStub(lock_opr, true, monitor_no); 1.359 + // temporary fix: must be created after exceptionhandler, therefore as call stub 1.360 + _slow_case_stubs->append(slow_case); 1.361 + if (UseFastLocking) { 1.362 + // try inlined fast unlocking first, revert to slow locking if it fails 1.363 + // note: lock_reg points to the displaced header since the displaced header offset is 0! 1.364 + assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); 1.365 + __ unlock_object(NOREG, obj_reg, lock_reg, *slow_case->entry()); 1.366 + } else { 1.367 + // always do slow unlocking 1.368 + // note: the slow unlocking code could be inlined here, however if we use 1.369 + // slow unlocking, speed doesn't matter anyway and this solution is 1.370 + // simpler and requires less duplicated code - additionally, the 1.371 + // slow unlocking code is the same in either case which simplifies 1.372 + // debugging 1.373 + __ b_far(*slow_case->entry()); 1.374 + __ delayed()->nop(); 1.375 + } 1.376 + // done 1.377 + __ bind(*slow_case->continuation()); 1.378 + 1.379 + if (exception->is_valid()) { 1.380 + // restore exception 1.381 + __ ld_ptr(exception, SP, 2 * wordSize); 1.382 + } 1.383 +} 1.384 + 1.385 +// This specifies the esp decrement needed to build the frame 1.386 +int LIR_Assembler::initial_frame_size_in_bytes() const { 1.387 + // if rounding, must let FrameMap know! 1.388 +// return (frame_map()->framesize() - 2) * BytesPerWord; // subtract two words to account for return address and link 1.389 + return (frame_map()->framesize() - (2*VMRegImpl::slots_per_word)) * VMRegImpl::stack_slot_size; 1.390 +} 1.391 + 1.392 +int LIR_Assembler::emit_exception_handler() { 1.393 + // if the last instruction is a call (typically to do a throw which 1.394 + // is coming at the end after block reordering) the return address 1.395 + // must still point into the code area in order to avoid assertion 1.396 + // failures when searching for the corresponding bci => add a nop 1.397 + // (was bug 5/14/1999 - gri) 1.398 + // Lazy deopt bug 4932387. If last instruction is a call then we 1.399 + // need an area to patch where we won't overwrite the exception 1.400 + // handler. This means we need 5 bytes. Could use a fat_nop 1.401 + // but since this never gets executed it doesn't really make 1.402 + // much difference. 1.403 + // 1.404 + for (int i = 0; i < (NativeCall::instruction_size/BytesPerInstWord + 1) ; i++ ) { 1.405 + __ nop(); 1.406 + } 1.407 + 1.408 + // generate code for exception handler 1.409 + address handler_base = __ start_a_stub(exception_handler_size); 1.410 + if (handler_base == NULL) { 1.411 + //no enough space 1.412 + bailout("exception handler overflow"); 1.413 + return -1; 1.414 + } 1.415 + 1.416 + 1.417 + 1.418 + //compilation()->offsets()->set_value(CodeOffsets::Exceptions, code_offset()); 1.419 + // if the method does not have an exception handler, then there is 1.420 + // no reason to search for one 1.421 + //if (compilation()->has_exception_handlers() || JvmtiExport::can_post_exceptions()) { 1.422 + // the exception oop and pc are in V0 and V1 1.423 + // no other registers need to be preserved, so invalidate them 1.424 + // check that there is really an exception 1.425 +// __ verify_not_null_oop(V0); 1.426 + 1.427 + // search an exception handler (V0: exception oop, V1: throwing pc) 1.428 +// __ call(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id), 1.429 +// relocInfo::runtime_call_type); 1.430 +// __ delayed()->nop(); 1.431 + // if the call returns here, then the exception handler for particular 1.432 + // exception doesn't exist -> unwind activation and forward exception to caller 1.433 + // } 1.434 + int offset = code_offset(); 1.435 + 1.436 + // the exception oop is in V0 1.437 + // no other registers need to be preserved, so invalidate them 1.438 + // check that there is really an exception 1.439 + __ verify_not_null_oop(V0); 1.440 + //FIXME:wuhui?? 1.441 + //__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_from_callee_id))); 1.442 + //__ delayed()->nop(); 1.443 + __ should_not_reach_here(); 1.444 + guarantee(code_offset() - offset <= exception_handler_size, "overflow"); 1.445 + __ end_a_stub(); 1.446 + return offset; 1.447 + 1.448 + // unlock the receiver/klass if necessary 1.449 + // V0: exception 1.450 +// ciMethod* method = compilation()->method(); 1.451 +// if (method->is_synchronized() && GenerateSynchronizationCode) { 1.452 +//#ifndef _LP64 1.453 +//by_css 1.454 +// monitorexit(FrameMap::_t0_oop_opr, FrameMap::_t6_opr, NOREG, 0, V0); 1.455 +//#else 1.456 +// monitorexit(FrameMap::_t0_oop_opr, FrameMap::_a6_opr, NOREG, 0, V0); 1.457 +//#endif 1.458 +// } 1.459 + 1.460 + // unwind activation and forward exception to caller 1.461 + // V0: exception 1.462 +// __ jmp(Runtime1::entry_for(Runtime1::unwind_exception_id), 1.463 +// relocInfo::runtime_call_type); 1.464 +// __ delayed()->nop(); 1.465 +// __ end_a_stub(); 1.466 +} 1.467 + 1.468 +// Emit the code to remove the frame from the stack in the exception 1.469 +// // unwind path. 1.470 +int LIR_Assembler::emit_unwind_handler() { 1.471 +#ifndef PRODUCT 1.472 + if (CommentedAssembly) { 1.473 + _masm->block_comment("Unwind handler"); 1.474 + } 1.475 +#endif 1.476 + 1.477 + int offset = code_offset(); 1.478 + /* // Fetch the exception from TLS and clear out exception related thread state 1.479 + __ get_thread(rsi); 1.480 + __ movptr(rax, Address(rsi, JavaThread::exception_oop_offset())); 1.481 + __ movptr(Address(rsi, JavaThread::exception_oop_offset()), (intptr_t)NULL_WORD); 1.482 + __ movptr(Address(rsi, JavaThread::exception_pc_offset()), (intptr_t)NULL_WORD); 1.483 + 1.484 + __ bind(_unwind_handler_entry); 1.485 + __ verify_not_null_oop(rax); 1.486 + if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { 1.487 + __ mov(rsi, rax); // Preserve the exception 1.488 + } 1.489 + // Preform needed unlocking 1.490 + MonitorExitStub* stub = NULL; 1.491 + if (method()->is_synchronized()) { 1.492 + monitor_address(0, FrameMap::rax_opr); 1.493 + stub = new MonitorExitStub(FrameMap::rax_opr, true, 0); 1.494 + __ unlock_object(rdi, rbx, rax, *stub->entry()); 1.495 + __ bind(*stub->continuation()); 1.496 + } 1.497 + 1.498 + if (compilation()->env()->dtrace_method_probes()) { 1.499 + __ get_thread(rax); 1.500 + __ movptr(Address(rsp, 0), rax); 1.501 + __ mov_metadata(Address(rsp, sizeof(void*)), method()->constant_encoding()); 1.502 + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit))); 1.503 + } 1.504 + 1.505 + if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { 1.506 + __ mov(rax, rsi); // Restore the exception 1.507 + } 1.508 + 1.509 + // remove the activation and dispatch to the unwind handler 1.510 + __ remove_frame(initial_frame_size_in_bytes()); 1.511 + __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id))); 1.512 + 1.513 + // Emit the slow path assembly 1.514 + if (stub != NULL) { 1.515 + stub->emit_code(this); 1.516 + } 1.517 +*/ 1.518 + return offset; 1.519 +} 1.520 + 1.521 + 1.522 +int LIR_Assembler::emit_deopt_handler() { 1.523 + // if the last instruction is a call (typically to do a throw which 1.524 + // is coming at the end after block reordering) the return address 1.525 + // must still point into the code area in order to avoid assertion 1.526 + // failures when searching for the corresponding bci => add a nop 1.527 + // (was bug 5/14/1999 - gri) 1.528 + 1.529 + __ nop(); 1.530 + 1.531 + // generate code for exception handler 1.532 + address handler_base = __ start_a_stub(deopt_handler_size); 1.533 + if (handler_base == NULL) { 1.534 + // not enough space left for the handler 1.535 + bailout("deopt handler overflow"); 1.536 + return -1; 1.537 + } 1.538 + int offset = code_offset(); 1.539 + 1.540 +// compilation()->offsets()->set_value(CodeOffsets::Deopt, code_offset()); 1.541 + 1.542 + __ call(SharedRuntime::deopt_blob()->unpack()); 1.543 + __ delayed()->nop(); 1.544 + 1.545 + guarantee(code_offset() - offset <= deopt_handler_size, "overflow"); 1.546 + __ end_a_stub(); 1.547 + return offset; 1.548 + 1.549 +} 1.550 + 1.551 + 1.552 +// Optimized Library calls 1.553 +// This is the fast version of java.lang.String.compare; it has not 1.554 +// OSR-entry and therefore, we generate a slow version for OSR's 1.555 +//void LIR_Assembler::emit_string_compare(IRScope* scope) { 1.556 +void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, CodeEmitInfo* info) { 1.557 + // get two string object in T0&T1 1.558 + //receiver already in T0 1.559 + __ ld_ptr(T1, arg1->as_register()); 1.560 + //__ ld_ptr(T2, T0, java_lang_String::value_offset_in_bytes()); //value, T_CHAR array 1.561 + __ load_heap_oop(T2, Address(T0, java_lang_String::value_offset_in_bytes())); 1.562 + __ ld_ptr(AT, T0, java_lang_String::offset_offset_in_bytes()); //offset 1.563 + __ shl(AT, 1); 1.564 + __ add(T2, T2, AT); 1.565 + __ addi(T2, T2, arrayOopDesc::base_offset_in_bytes(T_CHAR)); 1.566 + // Now T2 is the address of the first char in first string(T0) 1.567 + 1.568 + add_debug_info_for_null_check_here(info); 1.569 + //__ ld_ptr(T3, T1, java_lang_String::value_offset_in_bytes()); 1.570 + __ load_heap_oop(T3, Address(T1, java_lang_String::value_offset_in_bytes())); 1.571 + __ ld_ptr(AT, T1, java_lang_String::offset_offset_in_bytes()); 1.572 + __ shl(AT, 1); 1.573 + __ add(T3, T3, AT); 1.574 + __ addi(T3, T3, arrayOopDesc::base_offset_in_bytes(T_CHAR)); 1.575 + // Now T3 is the address of the first char in second string(T1) 1.576 + 1.577 +#ifndef _LP64 1.578 +//by_css 1.579 + // compute minimum length (in T4) and difference of lengths (V0) 1.580 + Label L; 1.581 + __ lw (T4, Address(T0, java_lang_String::count_offset_in_bytes())); 1.582 + // the length of the first string(T0) 1.583 + __ lw (T5, Address(T1, java_lang_String::count_offset_in_bytes())); 1.584 + // the length of the second string(T1) 1.585 + 1.586 + __ subu(V0, T4, T5); 1.587 + __ blez(V0, L); 1.588 + __ delayed()->nop(); 1.589 + __ move (T4, T5); 1.590 + __ bind (L); 1.591 + 1.592 + Label Loop, haveResult, LoopEnd; 1.593 + __ bind(Loop); 1.594 + __ beq(T4, R0, LoopEnd); 1.595 + __ delayed(); 1.596 + 1.597 + __ addi(T2, T2, 2); 1.598 + 1.599 + // compare current character 1.600 + __ lhu(T5, T2, -2); 1.601 + __ lhu(T6, T3, 0); 1.602 + __ bne(T5, T6, haveResult); 1.603 + __ delayed(); 1.604 + 1.605 + __ addi(T3, T3, 2); 1.606 + 1.607 + __ b(Loop); 1.608 + __ delayed()->addi(T4, T4, -1); 1.609 + 1.610 + __ bind(haveResult); 1.611 + __ subu(V0, T5, T6); 1.612 + 1.613 + __ bind(LoopEnd); 1.614 +#else 1.615 + // compute minimum length (in T4) and difference of lengths (V0) 1.616 + Label L; 1.617 + __ lw (A4, Address(T0, java_lang_String::count_offset_in_bytes())); 1.618 + // the length of the first string(T0) 1.619 + __ lw (A5, Address(T1, java_lang_String::count_offset_in_bytes())); 1.620 + // the length of the second string(T1) 1.621 + 1.622 + __ dsubu(V0, A4, A5); 1.623 + __ blez(V0, L); 1.624 + __ delayed()->nop(); 1.625 + __ move (A4, A5); 1.626 + __ bind (L); 1.627 + 1.628 + Label Loop, haveResult, LoopEnd; 1.629 + __ bind(Loop); 1.630 + __ beq(A4, R0, LoopEnd); 1.631 + __ delayed(); 1.632 + 1.633 + __ daddi(T2, T2, 2); 1.634 + 1.635 + // compare current character 1.636 + __ lhu(A5, T2, -2); 1.637 + __ lhu(A6, T3, 0); 1.638 + __ bne(A5, A6, haveResult); 1.639 + __ delayed(); 1.640 + 1.641 + __ daddi(T3, T3, 2); 1.642 + 1.643 + __ b(Loop); 1.644 + __ delayed()->addi(A4, A4, -1); 1.645 + 1.646 + __ bind(haveResult); 1.647 + __ dsubu(V0, A5, A6); 1.648 + 1.649 + __ bind(LoopEnd); 1.650 +#endif 1.651 + return_op(FrameMap::_v0_opr); 1.652 +} 1.653 + 1.654 + 1.655 +void LIR_Assembler::return_op(LIR_Opr result) { 1.656 + assert(result->is_illegal() || !result->is_single_cpu() || result->as_register() == V0, "word returns are in V0"); 1.657 + // Pop the stack before the safepoint code 1.658 + __ leave(); 1.659 +#ifndef _LP64 1.660 + //by aoqi 1.661 + __ lui(AT, Assembler::split_high((intptr_t)os::get_polling_page() 1.662 + + (SafepointPollOffset % os::vm_page_size()))); 1.663 + __ relocate(relocInfo::poll_return_type); 1.664 + __ lw(AT, AT, Assembler::split_low((intptr_t)os::get_polling_page() 1.665 + + (SafepointPollOffset % os::vm_page_size()))); 1.666 +#else 1.667 + #ifndef OPT_SAFEPOINT 1.668 + // do not know how to handle relocate yet. do not know li or li64 should be used neither. by aoqi. 20111207 FIXME. 1.669 + __ li48(AT, (intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())); 1.670 + __ relocate(relocInfo::poll_return_type); 1.671 + __ lw(AT, AT, 0); 1.672 + #else 1.673 + __ lui(AT, Assembler::split_high((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()))); 1.674 + __ relocate(relocInfo::poll_return_type); 1.675 + __ lw(AT, AT, Assembler::split_low((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()))); 1.676 + #endif 1.677 +#endif 1.678 + 1.679 + __ jr(RA); 1.680 + __ delayed()->nop(); 1.681 +} 1.682 + 1.683 +//read protect mem to R0 won't cause the exception only in godson-2e, So I modify R0 to AT .@jerome,11/25,2006 1.684 +int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { 1.685 + assert(info != NULL, "info must not be null for safepoint poll"); 1.686 + int offset = __ offset(); 1.687 + Register r = tmp->as_register(); 1.688 +#ifndef _LP64 1.689 +//by aoqi 1.690 + __ lui(r, Assembler::split_high((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()))); 1.691 + add_debug_info_for_branch(info); 1.692 + __ relocate(relocInfo::poll_type); 1.693 + __ lw(AT, r, Assembler::split_low((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()))); 1.694 +#else 1.695 + #ifndef OPT_SAFEPOINT 1.696 + // do not know how to handle relocate yet. do not know li or li64 should be used neither. by aoqi. 20111207 FIXME. 1.697 + //__ lui(r, Assembler::split_high((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()))); 1.698 + __ li48(r, (intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())); 1.699 + add_debug_info_for_branch(info); 1.700 + __ relocate(relocInfo::poll_type); 1.701 + //__ lw(AT, r, Assembler::split_low((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()))); 1.702 + __ lw(AT, r, 0); 1.703 + #else 1.704 + __ lui(r, Assembler::split_high((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()))); 1.705 + add_debug_info_for_branch(info); 1.706 + __ relocate(relocInfo::poll_type); 1.707 + __ lw(AT, r, Assembler::split_low((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()))); 1.708 + #endif 1.709 +#endif 1.710 + return offset; 1.711 +} 1.712 + 1.713 +void LIR_Assembler::move_regs(Register from_reg, Register to_reg) { 1.714 + if (from_reg != to_reg) __ move(to_reg, from_reg); 1.715 +} 1.716 + 1.717 + 1.718 +void LIR_Assembler::swap_reg(Register a, Register b) { 1.719 + __ xorr(a, a, b); 1.720 + __ xorr(b, a, b); 1.721 + __ xorr(a, a, b); 1.722 +} 1.723 + 1.724 +void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) { 1.725 + assert(src->is_constant(), "should not call otherwise"); 1.726 + assert(dest->is_register(), "should not call otherwise"); 1.727 + LIR_Const* c = src->as_constant_ptr(); 1.728 + switch (c->type()) { 1.729 + case T_INT: 1.730 + { 1.731 + jint con = c->as_jint(); 1.732 + if (dest->is_single_cpu()) { 1.733 + assert(patch_code == lir_patch_none, "no patching handled here"); 1.734 + __ move(dest->as_register(), con); 1.735 + } else { 1.736 + assert(dest->is_single_fpu(), "wrong register kind"); 1.737 + __ move(AT, con); 1.738 + __ mtc1(AT, dest->as_float_reg()); 1.739 + } 1.740 + } 1.741 + break; 1.742 + 1.743 + case T_LONG: 1.744 + { 1.745 +#ifndef _LP64 1.746 + jlong con = c->as_jlong(); 1.747 + jint* conhi = (jint*)&con + 1; 1.748 + jint* conlow = (jint*)&con; 1.749 + 1.750 + if (dest->is_double_cpu()) { 1.751 + __ move(dest->as_register_lo(), *conlow); 1.752 + __ move(dest->as_register_hi(), *conhi); 1.753 + } else { 1.754 + // assert(dest->is_double(), "wrong register kind"); 1.755 + __ move(AT, *conlow); 1.756 + __ mtc1(AT, dest->as_double_reg()); 1.757 + __ move(AT, *conhi); 1.758 + __ mtc1(AT, dest->as_double_reg()+1); 1.759 + } 1.760 +#else 1.761 + if (dest->is_double_cpu()) { 1.762 + __ li(dest->as_register_lo(), c->as_jlong()); 1.763 + } else { 1.764 + __ li(dest->as_register(), c->as_jlong()); 1.765 + } 1.766 +#endif 1.767 + } 1.768 + break; 1.769 + 1.770 + case T_OBJECT: 1.771 + { 1.772 + if (patch_code == lir_patch_none) { 1.773 + jobject2reg(c->as_jobject(), dest->as_register()); 1.774 + } else { 1.775 + jobject2reg_with_patching(dest->as_register(), info); 1.776 + } 1.777 + } 1.778 + break; 1.779 + 1.780 + case T_FLOAT: 1.781 + { 1.782 + address const_addr = float_constant(c->as_jfloat()); 1.783 + assert (const_addr != NULL, "must create float constant in the constant table"); 1.784 + 1.785 + if (dest->is_single_fpu()) { 1.786 + __ relocate(relocInfo::internal_pc_type); 1.787 +#ifndef _LP64 1.788 + //by_css 1.789 + __ lui(AT, Assembler::split_high((int)const_addr)); 1.790 + __ addiu(AT, AT, Assembler::split_low((int)const_addr)); 1.791 +#else 1.792 + __ li48(AT, (long)const_addr); 1.793 +#endif 1.794 + __ lwc1(dest->as_float_reg(), AT, 0); 1.795 + 1.796 + } else { 1.797 + assert(dest->is_single_cpu(), "Must be a cpu register."); 1.798 + assert(dest->as_register() != AT, "AT can not be allocated."); 1.799 + 1.800 + __ relocate(relocInfo::internal_pc_type); 1.801 +#ifndef _LP64 1.802 + //by_css 1.803 + __ lui(AT, Assembler::split_high((int)const_addr)); 1.804 + __ addiu(AT, AT, Assembler::split_low((int)const_addr)); 1.805 +#else 1.806 + __ li48(AT, (long)const_addr); 1.807 +#endif 1.808 + __ lw(dest->as_register(), AT, 0); 1.809 + } 1.810 + } 1.811 + break; 1.812 + 1.813 + case T_DOUBLE: 1.814 + { 1.815 + address const_addr = double_constant(c->as_jdouble()); 1.816 + assert (const_addr != NULL, "must create double constant in the constant table"); 1.817 + 1.818 + if (dest->is_double_fpu()) { 1.819 + __ relocate(relocInfo::internal_pc_type); 1.820 +#ifndef _LP64 1.821 + //by_css 1.822 + __ lui(AT, Assembler::split_high((int)const_addr)); 1.823 + __ addiu(AT, AT, Assembler::split_low((int)const_addr)); 1.824 + __ lwc1(dest->as_double_reg(), AT, 0); 1.825 + __ lwc1(dest->as_double_reg()+1, AT, 4); 1.826 +#else 1.827 + __ li48(AT, (long)const_addr); 1.828 + __ ldc1(dest->as_double_reg(), AT, 0); 1.829 +#endif 1.830 + } else { 1.831 + assert(dest->as_register_lo() != AT, "AT can not be allocated."); 1.832 + assert(dest->as_register_hi() != AT, "AT can not be allocated."); 1.833 + 1.834 + __ relocate(relocInfo::internal_pc_type); 1.835 +#ifndef _LP64 1.836 + //by_css 1.837 + __ lui(AT, Assembler::split_high((int)const_addr)); 1.838 + __ addiu(AT, AT, Assembler::split_low((int)const_addr)); 1.839 + __ lw(dest->as_register_lo(), AT, 0); 1.840 + __ lw(dest->as_register_hi(), AT, 4); 1.841 +#else 1.842 + __ li48(AT, (long)const_addr); 1.843 + __ ld(dest->as_register_lo(), AT, 0); 1.844 +#endif 1.845 + } 1.846 + } 1.847 + break; 1.848 + 1.849 + default: 1.850 + ShouldNotReachHere(); 1.851 + } 1.852 +} 1.853 + 1.854 + 1.855 +void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) { 1.856 + assert(src->is_constant(), "should not call otherwise"); 1.857 + assert(dest->is_stack(), "should not call otherwise"); 1.858 + LIR_Const* c = src->as_constant_ptr(); 1.859 + switch (c->type()) { 1.860 + case T_INT: // fall through 1.861 + case T_FLOAT: 1.862 + __ move(AT, c->as_jint_bits()); 1.863 + __ sw(AT, frame_map()->address_for_slot(dest->single_stack_ix())); 1.864 + break; 1.865 + 1.866 + case T_OBJECT: 1.867 + if (c->as_jobject() == NULL) { 1.868 + __ st_ptr(R0, frame_map()->address_for_slot(dest->single_stack_ix())); 1.869 + } else { 1.870 + int oop_index = __ oop_recorder()->find_index(c->as_jobject()); 1.871 + RelocationHolder rspec = oop_Relocation::spec(oop_index); 1.872 + __ relocate(rspec); 1.873 +#ifndef _LP64 1.874 + //by_css 1.875 + __ lui(AT, Assembler::split_high((int)c->as_jobject())); 1.876 + __ addiu(AT, AT, Assembler::split_low((int)c->as_jobject())); 1.877 +#else 1.878 + __ li48(AT, (long)c->as_jobject()); 1.879 +#endif 1.880 + __ st_ptr(AT, frame_map()->address_for_slot(dest->single_stack_ix())); 1.881 + } 1.882 + break; 1.883 + case T_LONG: // fall through 1.884 + case T_DOUBLE: 1.885 +#ifndef _LP64 1.886 + __ move(AT, c->as_jint_lo_bits()); 1.887 + __ sw(AT, frame_map()->address_for_slot(dest->double_stack_ix(), 1.888 + lo_word_offset_in_bytes)); 1.889 + __ move(AT, c->as_jint_hi_bits()); 1.890 + __ sw(AT, frame_map()->address_for_slot(dest->double_stack_ix(), 1.891 + hi_word_offset_in_bytes)); 1.892 +#else 1.893 + __ move(AT, c->as_jlong_bits()); 1.894 + __ sd(AT, frame_map()->address_for_slot(dest->double_stack_ix(), 1.895 + lo_word_offset_in_bytes)); 1.896 +#endif 1.897 + break; 1.898 + default: 1.899 + ShouldNotReachHere(); 1.900 + } 1.901 +} 1.902 + 1.903 +void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) { 1.904 + assert(src->is_constant(), "should not call otherwise"); 1.905 + assert(dest->is_address(), "should not call otherwise"); 1.906 + LIR_Const* c = src->as_constant_ptr(); 1.907 + LIR_Address* addr = dest->as_address_ptr(); 1.908 + 1.909 + int null_check_here = code_offset(); 1.910 + switch (type) { 1.911 + case T_LONG: // fall through 1.912 + case T_DOUBLE: 1.913 +#ifndef _LP64 1.914 + __ move(AT, c->as_jint_hi_bits()); 1.915 + __ sw(AT, as_Address_hi(addr)); 1.916 + __ move(AT, c->as_jint_lo_bits()); 1.917 + __ sw(AT, as_Address_lo(addr)); 1.918 +#else 1.919 + if(c->as_jlong_bits() != 0) 1.920 + { 1.921 + /* DoublePrint: -0.0 1.922 + * (gdb) print /x -9223372036854775808 1.923 + * $1 = 0x8000000000000000 1.924 + */ 1.925 + __ li64(AT, c->as_jlong_bits()); 1.926 + __ sd(AT, as_Address_lo(addr)); 1.927 + } 1.928 + else 1.929 + __ sd(R0, as_Address(addr)); 1.930 +#endif 1.931 + break; 1.932 + case T_OBJECT: // fall through 1.933 + case T_ARRAY: 1.934 + if (c->as_jobject() == NULL){ 1.935 + if (UseCompressedOops && !wide) { 1.936 + __ sw(R0, as_Address(addr)); 1.937 + } else { 1.938 + __ st_ptr(R0, as_Address(addr)); 1.939 + } 1.940 + } else { 1.941 + int oop_index = __ oop_recorder()->find_index(c->as_jobject()); 1.942 + RelocationHolder rspec = oop_Relocation::spec(oop_index); 1.943 + __ relocate(rspec); 1.944 +#ifndef _LP64 1.945 + __ lui(AT, Assembler::split_high((int)c->as_jobject())); 1.946 + __ addiu(AT, AT, Assembler::split_low((int)c->as_jobject())); 1.947 + __ st_ptr(AT, as_Address(addr)); 1.948 + null_check_here = code_offset(); 1.949 +#else 1.950 + //by_css 1.951 + __ li64(AT, (long)c->as_jobject()); 1.952 + if (UseCompressedOops && !wide) { 1.953 + __ encode_heap_oop(AT); 1.954 + null_check_here = code_offset(); 1.955 + __ sw(AT, as_Address(addr)); 1.956 + } else { 1.957 + __ st_ptr(AT, as_Address(addr)); 1.958 + } 1.959 +#endif 1.960 + } 1.961 + break; 1.962 + case T_INT: // fall through 1.963 + case T_FLOAT: 1.964 + if(c->as_jint_bits() != 0) 1.965 + { 1.966 + __ move(AT, c->as_jint_bits()); 1.967 + __ sw(AT, as_Address(addr)); 1.968 + } 1.969 + else 1.970 + __ sw(R0, as_Address(addr)); 1.971 + break; 1.972 + case T_BOOLEAN: // fall through 1.973 + case T_BYTE: 1.974 + if(c->as_jint() != 0) 1.975 + { 1.976 + __ move(AT, c->as_jint()); 1.977 + __ sb(AT, as_Address(addr)); 1.978 + } 1.979 + else 1.980 + __ sb(R0, as_Address(addr)); 1.981 + break; 1.982 + case T_CHAR: // fall through 1.983 + case T_SHORT: 1.984 + if(c->as_jint() != 0) 1.985 + { 1.986 + __ move(AT, c->as_jint()); 1.987 + __ sh(AT, as_Address(addr)); 1.988 + } 1.989 + else 1.990 + __ sh(R0, as_Address(addr)); 1.991 + break; 1.992 + default: ShouldNotReachHere(); 1.993 + }; 1.994 + if (info != NULL) add_debug_info_for_null_check(null_check_here, info); 1.995 +} 1.996 + 1.997 +void LIR_Assembler::reg2reg(LIR_Opr src, LIR_Opr dest) { 1.998 + assert(src->is_register(), "should not call otherwise"); 1.999 + assert(dest->is_register(), "should not call otherwise"); 1.1000 + if (dest->is_float_kind() && src->is_float_kind()) { 1.1001 + // float to float moves 1.1002 + if (dest->is_single_fpu()) { 1.1003 + assert(src->is_single_fpu(), "must both be float"); 1.1004 + __ mov_s(dest->as_float_reg(), src->as_float_reg()); 1.1005 + } else { 1.1006 + assert(src->is_double_fpu(), "must bothe be double"); 1.1007 + __ mov_d( dest->as_double_reg(),src->as_double_reg()); 1.1008 + } 1.1009 + } else if (!dest->is_float_kind() && !src->is_float_kind()) { 1.1010 + // int to int moves 1.1011 + if (dest->is_single_cpu()) { 1.1012 +#ifdef _LP64 1.1013 +//FIXME aoqi: copy from x86 1.1014 + if (src->type() == T_LONG) { 1.1015 + // Can do LONG -> OBJECT 1.1016 + move_regs(src->as_register_lo(), dest->as_register()); 1.1017 + return; 1.1018 + } 1.1019 +#endif 1.1020 + assert(src->is_single_cpu(), "must match"); 1.1021 + if (dest->type() == T_INT) { 1.1022 + __ move_u32(dest->as_register(), src->as_register()); 1.1023 + } 1.1024 + else 1.1025 + move_regs(src->as_register(), dest->as_register()); 1.1026 + } else if (dest->is_double_cpu()) { 1.1027 +#ifdef _LP64 1.1028 + if (src->type() == T_OBJECT || src->type() == T_ARRAY) { 1.1029 + // Surprising to me but we can see move of a long to t_object 1.1030 + __ verify_oop(src->as_register()); 1.1031 + move_regs(src->as_register(), dest->as_register_lo()); 1.1032 + return; 1.1033 + } 1.1034 +#endif 1.1035 + Register f_lo; 1.1036 + Register f_hi; 1.1037 + Register t_lo; 1.1038 + Register t_hi; 1.1039 + 1.1040 + if (src->is_single_cpu()) 1.1041 + { 1.1042 + f_lo = src->as_register(); 1.1043 + t_lo = dest->as_register_lo(); 1.1044 + } 1.1045 + else 1.1046 + { 1.1047 + f_lo = src->as_register_lo(); 1.1048 + f_hi = src->as_register_hi(); 1.1049 + t_lo = dest->as_register_lo(); 1.1050 + t_hi = dest->as_register_hi(); 1.1051 + assert(f_hi == f_lo, "must be same"); 1.1052 + assert(t_hi == t_lo, "must be same"); 1.1053 + } 1.1054 +#ifdef _LP64 1.1055 + move_regs(f_lo, t_lo); 1.1056 +#else 1.1057 + /* 1.1058 + if (src->as_register_hi() != dest->as_register_lo()) { 1.1059 + move_regs(src->as_register_lo(), dest->as_register_lo()); 1.1060 + move_regs(src->as_register_hi(), dest->as_register_hi()); 1.1061 + } else if (src->as_register_lo() != dest->as_register_hi()) { 1.1062 + move_regs(src->as_register_hi(), dest->as_register_hi()); 1.1063 + move_regs(src->as_register_lo(), dest->as_register_lo()); 1.1064 + } else { 1.1065 + swap_reg(src->as_register_lo(), src->as_register_hi()); 1.1066 + } 1.1067 + */ 1.1068 + assert(f_lo != f_hi && t_lo != t_hi, "invalid register allocation"); 1.1069 + 1.1070 + if (f_lo == t_hi && f_hi == t_lo) { 1.1071 + swap_reg(f_lo, f_hi); 1.1072 + } else if (f_hi == t_lo) { 1.1073 + assert(f_lo != t_hi, "overwriting register"); 1.1074 + move_regs(f_hi, t_hi); 1.1075 + move_regs(f_lo, t_lo); 1.1076 + } else { 1.1077 + assert(f_hi != t_lo, "overwriting register"); 1.1078 + move_regs(f_lo, t_lo); 1.1079 + move_regs(f_hi, t_hi); 1.1080 + } 1.1081 +#endif // LP64 1.1082 + } 1.1083 + } else { 1.1084 + // float to int or int to float moves 1.1085 + if (dest->is_double_cpu()) { 1.1086 + assert(src->is_double_fpu(), "must match"); 1.1087 + __ mfc1(dest->as_register_lo(), src->as_double_reg()); 1.1088 +#ifndef _LP64 1.1089 + __ mfc1(dest->as_register_hi(), src->as_double_reg() + 1); 1.1090 +#endif 1.1091 + } else if (dest->is_single_cpu()) { 1.1092 + assert(src->is_single_fpu(), "must match"); 1.1093 + __ mfc1(dest->as_register(), src->as_float_reg()); 1.1094 + } else if (dest->is_double_fpu()) { 1.1095 + assert(src->is_double_cpu(), "must match"); 1.1096 + __ mtc1(src->as_register_lo(), dest->as_double_reg()); 1.1097 +#ifndef _LP64 1.1098 + __ mtc1(src->as_register_hi(), dest->as_double_reg() + 1); 1.1099 +#endif 1.1100 + } else if (dest->is_single_fpu()) { 1.1101 + assert(src->is_single_cpu(), "must match"); 1.1102 + __ mtc1(src->as_register(), dest->as_float_reg()); 1.1103 + } 1.1104 + } 1.1105 +} 1.1106 + 1.1107 + 1.1108 +void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type,bool pop_fpu_stack) { 1.1109 + assert(src->is_register(), "should not call otherwise"); 1.1110 + assert(dest->is_stack(), "should not call otherwise"); 1.1111 + 1.1112 + if (src->is_single_cpu()) { 1.1113 + Address dst = frame_map()->address_for_slot(dest->single_stack_ix()); 1.1114 + if (type == T_OBJECT || type == T_ARRAY) { 1.1115 + __ verify_oop(src->as_register()); 1.1116 + } 1.1117 +#ifdef _LP64 1.1118 + if (type == T_INT) 1.1119 + __ sw(src->as_register(),dst); 1.1120 + else 1.1121 +#endif 1.1122 + __ st_ptr(src->as_register(),dst); 1.1123 + } else if (src->is_double_cpu()) { 1.1124 + Address dstLO = frame_map()->address_for_slot(dest->double_stack_ix(), lo_word_offset_in_bytes); 1.1125 + Address dstHI = frame_map()->address_for_slot(dest->double_stack_ix(), hi_word_offset_in_bytes); 1.1126 + __ st_ptr(src->as_register_lo(),dstLO); 1.1127 + NOT_LP64(__ st_ptr(src->as_register_hi(),dstHI)); 1.1128 + }else if (src->is_single_fpu()) { 1.1129 + Address dst_addr = frame_map()->address_for_slot(dest->single_stack_ix()); 1.1130 + __ swc1(src->as_float_reg(), dst_addr); 1.1131 + 1.1132 + } else if (src->is_double_fpu()) { 1.1133 + Address dst_addr = frame_map()->address_for_slot(dest->double_stack_ix()); 1.1134 +#ifndef _LP64 1.1135 + __ swc1(src->as_double_reg(), dst_addr); 1.1136 + __ swc1(src->as_double_reg() + 1, dst_addr.base(), dst_addr.disp() + 4); 1.1137 +#else 1.1138 + __ sdc1(src->as_double_reg(), dst_addr); 1.1139 +#endif 1.1140 + 1.1141 + } else { 1.1142 + ShouldNotReachHere(); 1.1143 + } 1.1144 +} 1.1145 + 1.1146 +//FIXME 1.1147 +void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info,bool pop_fpu_stack, bool wide, bool/*unaliged*/) { 1.1148 + LIR_Address* to_addr = dest->as_address_ptr(); 1.1149 + //Register dest_reg = to_addr->base()->as_register(); 1.1150 + // FIXME aoqi 1.1151 + Register dest_reg = to_addr->base()->is_single_cpu()? to_addr->base()->as_register() : to_addr->base()->as_register_lo(); 1.1152 + PatchingStub* patch = NULL; 1.1153 + bool needs_patching = (patch_code != lir_patch_none); 1.1154 + Register disp_reg = NOREG; 1.1155 + int disp_value = to_addr->disp(); 1.1156 + /* 1.1157 + the start position of patch template is labeled by "new PatchingStub(...)" 1.1158 + during patch, T9 will be changed and not restore 1.1159 + that's why we use S7 but not T9 as compressed_src here 1.1160 + */ 1.1161 + Register compressed_src = S7; 1.1162 + 1.1163 + if (type == T_ARRAY || type == T_OBJECT) { 1.1164 + __ verify_oop(src->as_register()); 1.1165 +#ifdef _LP64 1.1166 + if (UseCompressedOops && !wide) { 1.1167 + __ move(compressed_src, src->as_register()); 1.1168 + __ encode_heap_oop(compressed_src); 1.1169 + } 1.1170 +#endif 1.1171 + } 1.1172 + 1.1173 + if (needs_patching) { 1.1174 + patch = new PatchingStub(_masm, PatchingStub::access_field_id); 1.1175 + assert(!src->is_double_cpu() || 1.1176 + patch_code == lir_patch_none || 1.1177 + patch_code == lir_patch_normal, 1.1178 + "patching doesn't match register"); 1.1179 + Address toa = as_Address(to_addr); 1.1180 + assert(toa.disp() != 0, "must have"); 1.1181 + } 1.1182 + 1.1183 + if (info != NULL) { 1.1184 + add_debug_info_for_null_check_here(info); 1.1185 + } 1.1186 + if (needs_patching) { 1.1187 + disp_reg = AT; 1.1188 + __ lui(AT, Assembler::split_high(disp_value)); 1.1189 + __ addiu(AT, AT, Assembler::split_low(disp_value)); 1.1190 + } else if (!Assembler::is_simm16(disp_value)) { 1.1191 + disp_reg = AT; 1.1192 + __ lui(AT, Assembler::split_high(disp_value)); 1.1193 + } 1.1194 + int offset = code_offset(); 1.1195 + 1.1196 + switch(type) { 1.1197 + case T_DOUBLE: 1.1198 + assert(src->is_double_fpu(), "just check"); 1.1199 + if (disp_reg == noreg) { 1.1200 +#ifndef _LP64 1.1201 + __ swc1(src->as_double_reg(), dest_reg, disp_value); 1.1202 + __ swc1(src->as_double_reg()+1, dest_reg, disp_value+4); 1.1203 +#else 1.1204 + __ sdc1(src->as_double_reg(), dest_reg, disp_value); 1.1205 +#endif 1.1206 + } else if (needs_patching) { 1.1207 + __ add(AT, dest_reg, disp_reg); 1.1208 +#ifndef _LP64 1.1209 + __ swc1(src->as_double_reg(), AT, 0); 1.1210 + __ swc1(src->as_double_reg()+1, AT, 4); 1.1211 +#else 1.1212 + __ sdc1(src->as_double_reg(), AT, 0); 1.1213 +#endif 1.1214 + } else { 1.1215 + __ add(AT, dest_reg, disp_reg); 1.1216 +#ifndef _LP64 1.1217 + __ swc1(src->as_double_reg(), AT, Assembler::split_low(disp_value)); 1.1218 + __ swc1(src->as_double_reg()+1, AT, Assembler::split_low(disp_value) + 4); 1.1219 +#else 1.1220 + __ sdc1(src->as_double_reg(), AT, Assembler::split_low(disp_value)); 1.1221 +#endif 1.1222 + } 1.1223 + break; 1.1224 + 1.1225 + case T_FLOAT: 1.1226 + if (disp_reg == noreg) { 1.1227 + __ swc1(src->as_float_reg(), dest_reg, disp_value); 1.1228 + } else if(needs_patching) { 1.1229 + __ add(AT, dest_reg, disp_reg); 1.1230 + __ swc1(src->as_float_reg(), AT, 0); 1.1231 + } else { 1.1232 + __ add(AT, dest_reg, disp_reg); 1.1233 + __ swc1(src->as_float_reg(), AT, Assembler::split_low(disp_value)); 1.1234 + } 1.1235 + break; 1.1236 + 1.1237 + case T_LONG: { 1.1238 + Register from_lo = src->as_register_lo(); 1.1239 + Register from_hi = src->as_register_hi(); 1.1240 +#ifdef _LP64 1.1241 + if (needs_patching) { 1.1242 + __ add(AT, dest_reg, disp_reg); 1.1243 + __ st_ptr(from_lo, AT, 0); 1.1244 + } else { 1.1245 + __ st_ptr(from_lo, as_Address_lo(to_addr)); 1.1246 + } 1.1247 +#else 1.1248 + Register base = to_addr->base()->as_register(); 1.1249 + Register index = noreg; 1.1250 + if (to_addr->index()->is_register()) { 1.1251 + index = to_addr->index()->as_register(); 1.1252 + } 1.1253 + if (base == from_lo || index == from_lo) { 1.1254 + assert(base != from_hi, "can't be"); 1.1255 + assert(index == noreg || (index != base && index != from_hi), "can't handle this"); 1.1256 + if (needs_patching) { 1.1257 + __ add(AT, dest_reg, disp_reg); 1.1258 + NOT_LP64(__ st_ptr(from_hi, AT, longSize/2);) 1.1259 + __ st_ptr(from_lo, AT, 0); 1.1260 + } else { 1.1261 + __ st_ptr(from_hi, as_Address_hi(to_addr)); 1.1262 + __ st_ptr(from_lo, as_Address_lo(to_addr)); 1.1263 + } 1.1264 + } else { 1.1265 + assert(index == noreg || (index != base && index != from_lo), "can't handle this"); 1.1266 + if (needs_patching) { 1.1267 + __ add(AT, dest_reg, disp_reg); 1.1268 + __ st_ptr(from_lo, AT, 0); 1.1269 + __ st_ptr(from_hi, AT, longSize/2); 1.1270 + } else { 1.1271 + __ st_ptr(from_lo, as_Address_lo(to_addr)); 1.1272 + __ st_ptr(from_hi, as_Address_hi(to_addr)); 1.1273 + } 1.1274 + } 1.1275 +#endif 1.1276 + break; 1.1277 + } 1.1278 + case T_ARRAY: 1.1279 + case T_OBJECT: 1.1280 +#ifdef _LP64 1.1281 + if (UseCompressedOops && !wide) { 1.1282 + if (disp_reg == noreg) { 1.1283 + __ sw(compressed_src, dest_reg, disp_value); 1.1284 + } else if (needs_patching) { 1.1285 + __ add(AT, dest_reg, disp_reg); 1.1286 + __ sw(compressed_src, AT, 0); 1.1287 + } else { 1.1288 + __ add(AT, dest_reg, disp_reg); 1.1289 + __ sw(compressed_src, AT, Assembler::split_low(disp_value)); 1.1290 + } 1.1291 + } else { 1.1292 + if (disp_reg == noreg) { 1.1293 + __ st_ptr(src->as_register(), dest_reg, disp_value); 1.1294 + } else if (needs_patching) { 1.1295 + __ add(AT, dest_reg, disp_reg); 1.1296 + __ st_ptr(src->as_register(), AT, 0); 1.1297 + } else { 1.1298 + __ add(AT, dest_reg, disp_reg); 1.1299 + __ st_ptr(src->as_register(), AT, Assembler::split_low(disp_value)); 1.1300 + } 1.1301 + } 1.1302 + break; 1.1303 +#endif 1.1304 + case T_ADDRESS: 1.1305 +#ifdef _LP64 1.1306 + if (disp_reg == noreg) { 1.1307 + __ st_ptr(src->as_register(), dest_reg, disp_value); 1.1308 + } else if (needs_patching) { 1.1309 + __ add(AT, dest_reg, disp_reg); 1.1310 + __ st_ptr(src->as_register(), AT, 0); 1.1311 + } else { 1.1312 + __ add(AT, dest_reg, disp_reg); 1.1313 + __ st_ptr(src->as_register(), AT, Assembler::split_low(disp_value)); 1.1314 + } 1.1315 + break; 1.1316 +#endif 1.1317 + case T_INT: 1.1318 + if (disp_reg == noreg) { 1.1319 + __ sw(src->as_register(), dest_reg, disp_value); 1.1320 + } else if (needs_patching) { 1.1321 + __ add(AT, dest_reg, disp_reg); 1.1322 + __ sw(src->as_register(), AT, 0); 1.1323 + } else { 1.1324 + __ add(AT, dest_reg, disp_reg); 1.1325 + __ sw(src->as_register(), AT, Assembler::split_low(disp_value)); 1.1326 + } 1.1327 + break; 1.1328 + 1.1329 + case T_CHAR: 1.1330 + case T_SHORT: 1.1331 + if (disp_reg == noreg) { 1.1332 + __ sh(src->as_register(), dest_reg, disp_value); 1.1333 + } else if (needs_patching) { 1.1334 + __ add(AT, dest_reg, disp_reg); 1.1335 + __ sh(src->as_register(), AT, 0); 1.1336 + } else { 1.1337 + __ add(AT, dest_reg, disp_reg); 1.1338 + __ sh(src->as_register(), AT, Assembler::split_low(disp_value)); 1.1339 + } 1.1340 + break; 1.1341 + 1.1342 + case T_BYTE: 1.1343 + case T_BOOLEAN: 1.1344 + assert(src->is_single_cpu(), "just check"); 1.1345 + 1.1346 + if (disp_reg == noreg) { 1.1347 + __ sb(src->as_register(), dest_reg, disp_value); 1.1348 + } else if (needs_patching) { 1.1349 + __ add(AT, dest_reg, disp_reg); 1.1350 + __ sb(src->as_register(), AT, 0); 1.1351 + } else { 1.1352 + __ add(AT, dest_reg, disp_reg); 1.1353 + __ sb(src->as_register(), AT, Assembler::split_low(disp_value)); 1.1354 + } 1.1355 + break; 1.1356 + 1.1357 + default: 1.1358 + ShouldNotReachHere(); 1.1359 + } 1.1360 + 1.1361 + 1.1362 + if (needs_patching) { 1.1363 + patching_epilog(patch, patch_code, to_addr->base()->as_register(), info); 1.1364 + } 1.1365 +} 1.1366 + 1.1367 + 1.1368 + 1.1369 +void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { 1.1370 + assert(src->is_stack(), "should not call otherwise"); 1.1371 + assert(dest->is_register(), "should not call otherwise"); 1.1372 + if (dest->is_single_cpu()) { 1.1373 +#ifdef _LP64 1.1374 + if (type == T_INT) 1.1375 + __ lw(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); 1.1376 + else 1.1377 +#endif 1.1378 + __ ld_ptr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); 1.1379 + if (type == T_ARRAY || type == T_OBJECT) { 1.1380 + __ verify_oop(dest->as_register()); 1.1381 + } 1.1382 + } else if (dest->is_double_cpu()) { 1.1383 +#ifdef _LP64 1.1384 +/* java.util.concurrent.locks.ReentrantReadWriteLock$Sync::tryAcquire 1.1385 + 1.1386 + 88 move [stack:2|L] [a5a5|J] 1.1387 +OpenJDK 64-Bit Client VM warning: /mnt/openjdk6-mips/hotspot/src/share/c1/c1_LIR.hpp, 397 , assert(is_double_stack() && !is_virtual(),"type check") 1.1388 +OpenJDK 64-Bit Client VM warning: /mnt/openjdk6-mips/hotspot/src/share/c1/c1_LIR.hpp, 397 , assert(is_double_stack() && !is_virtual(),"type check") 1.1389 + 0x000000556197af8c: ld a5, 0x50(sp) 1.1390 +*/ 1.1391 + Address src_addr_LO; 1.1392 + if (src->is_single_stack()) 1.1393 + src_addr_LO = frame_map()->address_for_slot(src->single_stack_ix(),lo_word_offset_in_bytes); 1.1394 + else if (src->is_double_stack()) 1.1395 + src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix(),lo_word_offset_in_bytes); 1.1396 + else 1.1397 + ShouldNotReachHere(); 1.1398 +#else 1.1399 + Address src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix(),lo_word_offset_in_bytes); 1.1400 + Address src_addr_HI = frame_map()->address_for_slot(src->double_stack_ix(), hi_word_offset_in_bytes); 1.1401 +#endif 1.1402 +#ifdef _LP64 1.1403 + if (src->type() == T_INT) 1.1404 + __ lw(dest->as_register_lo(), src_addr_LO); 1.1405 + else 1.1406 +#endif 1.1407 + __ ld_ptr(dest->as_register_lo(), src_addr_LO); 1.1408 + NOT_LP64(__ ld_ptr(dest->as_register_hi(), src_addr_HI)); 1.1409 + }else if (dest->is_single_fpu()) { 1.1410 + Address addr = frame_map()->address_for_slot(src->single_stack_ix()); 1.1411 + __ lwc1(dest->as_float_reg(), addr); 1.1412 + } else if (dest->is_double_fpu()) { 1.1413 + Address src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix(),lo_word_offset_in_bytes); 1.1414 +#ifndef _LP64 1.1415 + Address src_addr_HI = frame_map()->address_for_slot(src->double_stack_ix(), hi_word_offset_in_bytes); 1.1416 + __ lwc1(dest->as_double_reg(), src_addr_LO); 1.1417 + __ lwc1(dest->as_double_reg()+1, src_addr_HI); 1.1418 +#else 1.1419 + __ ldc1(dest->as_double_reg(), src_addr_LO); 1.1420 +#endif 1.1421 + } else { 1.1422 + ShouldNotReachHere(); 1.1423 + /* 1.1424 + assert(dest->is_single_cpu(), "cannot be anything else but a single cpu"); 1.1425 + assert(type!= T_ILLEGAL, "Bad type in stack2reg") 1.1426 + Address addr = frame_map()->address_for_slot(src->single_stack_ix()); 1.1427 + __ lw(dest->as_register(), addr); 1.1428 + */ 1.1429 + } 1.1430 +} 1.1431 + 1.1432 +void LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) { 1.1433 + if (src->is_single_stack()) { 1.1434 + /* 1.1435 + * 2012/5/23 Jin: YozoOffice(-Xcomp) corrupts in "New File -> word" 1.1436 + * 1.1437 + * [b.q.e.a.z::bw()] 1.1438 + * move [stack:15|L] [stack:17|L] 1.1439 + * 0x00000055584e7cf4: lw at, 0x78(sp) <--- error! 1.1440 + * 0x00000055584e7cf8: sw at, 0x88(sp) 1.1441 + */ 1.1442 + if (type == T_OBJECT ) 1.1443 + { 1.1444 + __ ld(AT, frame_map()->address_for_slot(src ->single_stack_ix())); 1.1445 + __ sd(AT, frame_map()->address_for_slot(dest->single_stack_ix())); 1.1446 + } 1.1447 + else 1.1448 + { 1.1449 + __ lw(AT, frame_map()->address_for_slot(src ->single_stack_ix())); 1.1450 + __ sw(AT, frame_map()->address_for_slot(dest->single_stack_ix())); 1.1451 + } 1.1452 + } else if (src->is_double_stack()) { 1.1453 +#ifndef _LP64 1.1454 + __ lw(AT, frame_map()->address_for_slot(src ->double_stack_ix())); 1.1455 + __ sw(AT, frame_map()->address_for_slot(dest->double_stack_ix())); 1.1456 + __ lw(AT, frame_map()->address_for_slot(src ->double_stack_ix(),4)); 1.1457 + __ sw(AT, frame_map()->address_for_slot(dest ->double_stack_ix(),4)); 1.1458 +#else 1.1459 + __ ld_ptr(AT, frame_map()->address_for_slot(src ->double_stack_ix())); 1.1460 + __ st_ptr(AT, frame_map()->address_for_slot(dest->double_stack_ix())); 1.1461 +#endif 1.1462 + } else { 1.1463 + ShouldNotReachHere(); 1.1464 + } 1.1465 +} 1.1466 + 1.1467 +// if patching needed, be sure the instruction at offset is a MoveMemReg 1.1468 +void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool) { 1.1469 + assert(src->is_address(), "should not call otherwise"); 1.1470 + assert(dest->is_register(), "should not call otherwise"); 1.1471 + LIR_Address* addr = src->as_address_ptr(); 1.1472 + //Address from_addr = as_Address(addr); 1.1473 + 1.1474 + //Register src_reg = addr->base()->as_register(); 1.1475 + // FIXME aoqi 1.1476 + Register src_reg = addr->base()->is_single_cpu()? addr->base()->as_register() : addr->base()->as_register_lo(); 1.1477 + Register disp_reg = noreg; 1.1478 + int disp_value = addr->disp(); 1.1479 + bool needs_patching = (patch_code != lir_patch_none); 1.1480 + 1.1481 + PatchingStub* patch = NULL; 1.1482 + if (needs_patching) { 1.1483 + patch = new PatchingStub(_masm, PatchingStub::access_field_id); 1.1484 + } 1.1485 + 1.1486 + // we must use lui&addiu, 1.1487 + if (needs_patching) { 1.1488 + disp_reg = AT; 1.1489 + __ lui(AT, Assembler::split_high(disp_value)); 1.1490 + __ addiu(AT, AT, Assembler::split_low(disp_value)); 1.1491 + } else if (!Assembler::is_simm16(disp_value)) { 1.1492 + disp_reg = AT; 1.1493 + __ lui(AT, Assembler::split_high(disp_value)); 1.1494 + } 1.1495 + 1.1496 + // remember the offset of the load. The patching_epilog must be done 1.1497 + // before the call to add_debug_info, otherwise the PcDescs don't get 1.1498 + // entered in increasing order. 1.1499 + int offset = code_offset(); 1.1500 + 1.1501 + switch(type) { 1.1502 + case T_BOOLEAN: 1.1503 + case T_BYTE: { 1.1504 + //assert(to_reg.is_word(), "just check"); 1.1505 + if (disp_reg == noreg) { 1.1506 + __ lb(dest->as_register(), src_reg, disp_value); 1.1507 + } else if (needs_patching) { 1.1508 + __ add(AT, src_reg, disp_reg); 1.1509 + offset = code_offset(); 1.1510 + __ lb(dest->as_register(), AT, 0); 1.1511 + } else { 1.1512 + __ add(AT, src_reg, disp_reg); 1.1513 + offset = code_offset(); 1.1514 + __ lb(dest->as_register(), AT, Assembler::split_low(disp_value)); 1.1515 + } 1.1516 + } 1.1517 + break; 1.1518 + 1.1519 + case T_CHAR: { 1.1520 + //assert(to_reg.is_word(), "just check"); 1.1521 + if (disp_reg == noreg) { 1.1522 + __ lhu(dest->as_register(), src_reg, disp_value); 1.1523 + } else if (needs_patching) { 1.1524 + __ add(AT, src_reg, disp_reg); 1.1525 + offset = code_offset(); 1.1526 + __ lhu(dest->as_register(), AT, 0); 1.1527 + } else { 1.1528 + __ add(AT, src_reg, disp_reg); 1.1529 + offset = code_offset(); 1.1530 + __ lhu(dest->as_register(), AT, Assembler::split_low(disp_value)); 1.1531 + } 1.1532 + } 1.1533 + break; 1.1534 + 1.1535 + case T_SHORT: { 1.1536 + // assert(to_reg.is_word(), "just check"); 1.1537 + if (disp_reg == noreg) { 1.1538 + __ lh(dest->as_register(), src_reg, disp_value); 1.1539 + } else if (needs_patching) { 1.1540 + __ add(AT, src_reg, disp_reg); 1.1541 + offset = code_offset(); 1.1542 + __ lh(dest->as_register(), AT, 0); 1.1543 + } else { 1.1544 + __ add(AT, src_reg, disp_reg); 1.1545 + offset = code_offset(); 1.1546 + __ lh(dest->as_register(), AT, Assembler::split_low(disp_value)); 1.1547 + } 1.1548 + } 1.1549 + break; 1.1550 + 1.1551 + case T_OBJECT: 1.1552 + case T_ARRAY: 1.1553 + if (UseCompressedOops && !wide) { 1.1554 + if (disp_reg == noreg) { 1.1555 + __ lw(dest->as_register(), src_reg, disp_value); 1.1556 + } else if (needs_patching) { 1.1557 + __ dadd(AT, src_reg, disp_reg); 1.1558 + offset = code_offset(); 1.1559 + __ lw(dest->as_register(), AT, 0); 1.1560 + } else { 1.1561 + __ dadd(AT, src_reg, disp_reg); 1.1562 + offset = code_offset(); 1.1563 + __ lw(dest->as_register(), AT, Assembler::split_low(disp_value)); 1.1564 + } 1.1565 + 1.1566 + } else { 1.1567 + if (disp_reg == noreg) { 1.1568 + __ ld_ptr(dest->as_register(), src_reg, disp_value); 1.1569 + } else if (needs_patching) { 1.1570 + __ dadd(AT, src_reg, disp_reg); 1.1571 + offset = code_offset(); 1.1572 + __ ld_ptr(dest->as_register(), AT, 0); 1.1573 + } else { 1.1574 + __ dadd(AT, src_reg, disp_reg); 1.1575 + offset = code_offset(); 1.1576 + __ ld_ptr(dest->as_register(), AT, Assembler::split_low(disp_value)); 1.1577 + } 1.1578 + } 1.1579 + break; 1.1580 + case T_ADDRESS: 1.1581 + if (disp_reg == noreg) { 1.1582 + __ ld_ptr(dest->as_register(), src_reg, disp_value); 1.1583 + } else if (needs_patching) { 1.1584 + __ dadd(AT, src_reg, disp_reg); 1.1585 + offset = code_offset(); 1.1586 + __ ld_ptr(dest->as_register(), AT, 0); 1.1587 + } else { 1.1588 + __ dadd(AT, src_reg, disp_reg); 1.1589 + offset = code_offset(); 1.1590 + __ ld_ptr(dest->as_register(), AT, Assembler::split_low(disp_value)); 1.1591 + } 1.1592 + break; 1.1593 + case T_INT: { 1.1594 + //assert(to_reg.is_word(), "just check"); 1.1595 + if (disp_reg == noreg) { 1.1596 + __ lw(dest->as_register(), src_reg, disp_value); 1.1597 + } else if (needs_patching) { 1.1598 + __ add(AT, src_reg, disp_reg); 1.1599 + offset = code_offset(); 1.1600 + __ lw(dest->as_register(), AT, 0); 1.1601 + } else { 1.1602 + __ add(AT, src_reg, disp_reg); 1.1603 + offset = code_offset(); 1.1604 + __ lw(dest->as_register(), AT, Assembler::split_low(disp_value)); 1.1605 + } 1.1606 + } 1.1607 + break; 1.1608 + 1.1609 + case T_LONG: { 1.1610 + Register to_lo = dest->as_register_lo(); 1.1611 + Register to_hi = dest->as_register_hi(); 1.1612 +#ifdef _LP64 1.1613 + if (needs_patching) { 1.1614 + __ add(AT, src_reg, disp_reg); 1.1615 + __ ld_ptr(to_lo, AT, 0); 1.1616 + } else { 1.1617 + __ ld_ptr(to_lo, as_Address_lo(addr)); 1.1618 + } 1.1619 +#else 1.1620 + Register base = addr->base()->as_register(); 1.1621 + Register index = noreg; 1.1622 + if (addr->index()->is_register()) { 1.1623 + index = addr->index()->as_register(); 1.1624 + } 1.1625 + if ((base == to_lo && index == to_hi) ||(base == to_hi && index == to_lo)) { 1.1626 + // addresses with 2 registers are only formed as a result of 1.1627 + // array access so this code will never have to deal with 1.1628 + // patches or null checks. 1.1629 + assert(info == NULL && patch == NULL, "must be"); 1.1630 + __ lea(to_hi, as_Address(addr)); 1.1631 + __ lw(to_lo, Address(to_hi)); 1.1632 + __ lw(to_hi, Address(to_hi, BytesPerWord)); 1.1633 + } else if (base == to_lo || index == to_lo) { 1.1634 + assert(base != to_hi, "can't be"); 1.1635 + assert(index == noreg || (index != base && index != to_hi), "can't handle this"); 1.1636 + if (needs_patching) { 1.1637 + __ add(AT, src_reg, disp_reg); 1.1638 + offset = code_offset(); 1.1639 + __ lw(to_hi, AT, longSize/2); 1.1640 + __ lw(to_lo, AT, 0); 1.1641 + } else { 1.1642 + __ lw(to_hi, as_Address_hi(addr)); 1.1643 + __ lw(to_lo, as_Address_lo(addr)); 1.1644 + } 1.1645 + } else { 1.1646 + assert(index == noreg || (index != base && index != to_lo), "can't handle this"); 1.1647 + if (needs_patching) { 1.1648 + __ add(AT, src_reg, disp_reg); 1.1649 + offset = code_offset(); 1.1650 + __ lw(to_lo, AT, 0); 1.1651 + __ lw(to_hi, AT, longSize/2); 1.1652 + } else { 1.1653 + __ lw(to_lo, as_Address_lo(addr)); 1.1654 + __ lw(to_hi, as_Address_hi(addr)); 1.1655 + } 1.1656 + } 1.1657 +#endif 1.1658 + } 1.1659 + break; 1.1660 + 1.1661 + case T_FLOAT: { 1.1662 + //assert(to_reg.is_float(), "just check"); 1.1663 + if (disp_reg == noreg) { 1.1664 + __ lwc1(dest->as_float_reg(), src_reg, disp_value); 1.1665 + } else if (needs_patching) { 1.1666 + __ add(AT, src_reg, disp_reg); 1.1667 + offset = code_offset(); 1.1668 + __ lwc1(dest->as_float_reg(), AT, 0); 1.1669 + } else { 1.1670 + __ add(AT, src_reg, disp_reg); 1.1671 + offset = code_offset(); 1.1672 + __ lwc1(dest->as_float_reg(), AT, Assembler::split_low(disp_value)); 1.1673 + } 1.1674 + } 1.1675 + break; 1.1676 + 1.1677 + case T_DOUBLE: { 1.1678 + //assert(to_reg.is_double(), "just check"); 1.1679 + 1.1680 + if (disp_reg == noreg) { 1.1681 +#ifndef _LP64 1.1682 + __ lwc1(dest->as_double_reg(), src_reg, disp_value); 1.1683 + __ lwc1(dest->as_double_reg()+1, src_reg, disp_value+4); 1.1684 +#else 1.1685 + __ ldc1(dest->as_double_reg(), src_reg, disp_value); 1.1686 +#endif 1.1687 + } else if (needs_patching) { 1.1688 + __ add(AT, src_reg, disp_reg); 1.1689 + offset = code_offset(); 1.1690 +#ifndef _LP64 1.1691 + __ lwc1(dest->as_double_reg(), AT, 0); 1.1692 + __ lwc1(dest->as_double_reg()+1, AT, 4); 1.1693 +#else 1.1694 + __ ldc1(dest->as_double_reg(), AT, 0); 1.1695 +#endif 1.1696 + } else { 1.1697 + __ add(AT, src_reg, disp_reg); 1.1698 + offset = code_offset(); 1.1699 +#ifndef _LP64 1.1700 + __ lwc1(dest->as_double_reg(), AT, Assembler::split_low(disp_value)); 1.1701 + __ lwc1(dest->as_double_reg()+1, AT, Assembler::split_low(disp_value) + 4); 1.1702 +#else 1.1703 + __ ldc1(dest->as_double_reg(), AT, Assembler::split_low(disp_value)); 1.1704 +#endif 1.1705 + } 1.1706 + } 1.1707 + break; 1.1708 + 1.1709 + default: 1.1710 + ShouldNotReachHere(); 1.1711 + } 1.1712 + 1.1713 + if (needs_patching) { 1.1714 + patching_epilog(patch, patch_code, src_reg, info); 1.1715 + } 1.1716 + 1.1717 + if (type == T_ARRAY || type == T_OBJECT) { 1.1718 +#ifdef _LP64 1.1719 + if (UseCompressedOops && !wide) { 1.1720 + __ decode_heap_oop(dest->as_register()); 1.1721 + } 1.1722 +#endif 1.1723 + __ verify_oop(dest->as_register()); 1.1724 + } 1.1725 + if (info != NULL) add_debug_info_for_null_check(offset, info); 1.1726 +} 1.1727 + 1.1728 + 1.1729 +void LIR_Assembler::prefetchr(LIR_Opr src) { 1.1730 + LIR_Address* addr = src->as_address_ptr(); 1.1731 + Address from_addr = as_Address(addr); 1.1732 +} 1.1733 + 1.1734 + 1.1735 +void LIR_Assembler::prefetchw(LIR_Opr src) { 1.1736 +} 1.1737 + 1.1738 +NEEDS_CLEANUP; // This could be static? 1.1739 +Address::ScaleFactor LIR_Assembler::array_element_size(BasicType type) const { 1.1740 + int elem_size = type2aelembytes(type); 1.1741 + switch (elem_size) { 1.1742 + case 1: return Address::times_1; 1.1743 + case 2: return Address::times_2; 1.1744 + case 4: return Address::times_4; 1.1745 + case 8: return Address::times_8; 1.1746 + } 1.1747 + ShouldNotReachHere(); 1.1748 + return Address::no_scale; 1.1749 +} 1.1750 + 1.1751 + 1.1752 +void LIR_Assembler::emit_op3(LIR_Op3* op) { 1.1753 + switch (op->code()) { 1.1754 + case lir_frem: 1.1755 + arithmetic_frem( 1.1756 + op->code(), 1.1757 + op->in_opr1(), 1.1758 + op->in_opr2(), 1.1759 + op->in_opr3(), 1.1760 + op->result_opr(), 1.1761 + op->info()); 1.1762 + break; 1.1763 + 1.1764 + case lir_idiv: 1.1765 + case lir_irem: 1.1766 + arithmetic_idiv( 1.1767 + op->code(), 1.1768 + op->in_opr1(), 1.1769 + op->in_opr2(), 1.1770 + op->in_opr3(), 1.1771 + op->result_opr(), 1.1772 + op->info()); 1.1773 + break; 1.1774 + default: ShouldNotReachHere(); break; 1.1775 + } 1.1776 +} 1.1777 + 1.1778 +void LIR_Assembler::emit_opBranch(LIR_OpBranch* op) { 1.1779 + LIR_Opr opr1 = op->left(); 1.1780 + LIR_Opr opr2 = op->right(); 1.1781 + LIR_Condition condition = op->cond(); 1.1782 +#ifdef ASSERT 1.1783 + assert(op->block() == NULL || op->block()->label() == op->label(), "wrong label"); 1.1784 + if (op->block() != NULL) _branch_target_blocks.append(op->block()); 1.1785 + if (op->ublock() != NULL) _branch_target_blocks.append(op->ublock()); 1.1786 +#endif 1.1787 + if (op->cond() == lir_cond_always) { 1.1788 + if(op->label()==NULL) //by liaob1 1.1789 + __ b(*op->label()); 1.1790 + else 1.1791 + __ b_far(*op->label()); 1.1792 + __ delayed()->nop(); 1.1793 + return; 1.1794 + } 1.1795 + if (opr1->is_single_cpu()) { 1.1796 + Register reg_op1 = opr1->as_register(); 1.1797 + if (opr2->is_single_cpu()) { 1.1798 +#ifdef OPT_RANGECHECK 1.1799 + assert(!op->check(), "just check"); 1.1800 +#endif 1.1801 + Register reg_op2 = opr2->as_register(); 1.1802 + switch (condition) { 1.1803 + case lir_cond_equal: 1.1804 + __ beq(reg_op1, reg_op2, *op->label()); 1.1805 + break; 1.1806 + case lir_cond_notEqual: 1.1807 + if(op->label()==NULL) 1.1808 + __ bne(reg_op1, reg_op2, *op->label());//liaobin1 1.1809 + else 1.1810 + __ bne_far(reg_op1, reg_op2, *op->label());//liaobin1 1.1811 + break; 1.1812 + case lir_cond_less: 1.1813 + // AT = 1 TRUE 1.1814 + __ slt(AT, reg_op1, reg_op2); 1.1815 + __ bne_far(AT, R0, *op->label()); 1.1816 + break; 1.1817 + case lir_cond_lessEqual: 1.1818 + // AT = 0 TRUE 1.1819 + __ slt(AT, reg_op2, reg_op1); 1.1820 + __ beq_far(AT, R0, *op->label()); 1.1821 + break; 1.1822 + case lir_cond_belowEqual: 1.1823 + // AT = 0 TRUE 1.1824 + __ sltu(AT, reg_op2, reg_op1); 1.1825 + __ beq(AT, R0, *op->label()); 1.1826 + break; 1.1827 + case lir_cond_greaterEqual: 1.1828 + // AT = 0 TRUE 1.1829 + __ slt(AT, reg_op1, reg_op2); 1.1830 + __ beq_far(AT, R0, *op->label()); 1.1831 + break; 1.1832 + case lir_cond_aboveEqual: 1.1833 + // AT = 0 TRUE 1.1834 + __ sltu(AT, reg_op1, reg_op2); 1.1835 + __ beq_far(AT, R0, *op->label()); 1.1836 + break; 1.1837 + case lir_cond_greater: 1.1838 + // AT = 1 TRUE 1.1839 + __ slt(AT, reg_op2, reg_op1); 1.1840 + __ bne_far(AT, R0, *op->label()); 1.1841 + break; 1.1842 + default: ShouldNotReachHere(); 1.1843 + } 1.1844 + } else if (opr2->is_constant()) { 1.1845 + NOT_LP64(jint) LP64_ONLY(jlong) temp_value; 1.1846 + bool is_object = false; 1.1847 + if (opr2->pointer()->as_constant()->type() == T_INT) { 1.1848 + temp_value = (jint)(opr2->as_jint()); 1.1849 + } else if (opr2->pointer()->as_constant()->type() == T_LONG) { 1.1850 + temp_value = (jlong)(opr2->as_jlong()); 1.1851 + } else if (opr2->pointer()->as_constant()->type() == T_OBJECT) { 1.1852 + is_object = true; 1.1853 + temp_value = NOT_LP64((jint)) LP64_ONLY((jlong))(opr2->as_jobject()); 1.1854 + } else { 1.1855 + ShouldNotReachHere(); 1.1856 + } 1.1857 + 1.1858 + switch (condition) { 1.1859 + case lir_cond_equal: 1.1860 +#ifdef OPT_RANGECHECK 1.1861 + assert(!op->check(), "just check"); 1.1862 +#endif 1.1863 + if (temp_value) { 1.1864 + if (is_object) { 1.1865 + int oop_index = __ oop_recorder()->allocate_oop_index((jobject)temp_value); 1.1866 + RelocationHolder rspec = oop_Relocation::spec(oop_index); 1.1867 + __ relocate(rspec); 1.1868 + } 1.1869 + __ li(AT, temp_value); 1.1870 + __ beq_far(reg_op1, AT, *op->label()); 1.1871 + } else { 1.1872 + __ beq_far(reg_op1, R0, *op->label()); 1.1873 + } 1.1874 + break; 1.1875 + 1.1876 + case lir_cond_notEqual: 1.1877 +#ifdef OPT_RANGECHECK 1.1878 + assert(!op->check(), "just check"); 1.1879 +#endif 1.1880 + if (temp_value) { 1.1881 + if (is_object) { 1.1882 + int oop_index = __ oop_recorder()->allocate_oop_index((jobject)temp_value); 1.1883 + RelocationHolder rspec = oop_Relocation::spec(oop_index); 1.1884 + __ relocate(rspec); 1.1885 + } 1.1886 + __ li(AT, temp_value); 1.1887 + __ bne_far(reg_op1, AT, *op->label()); 1.1888 + } else { 1.1889 + __ bne_far(reg_op1, R0, *op->label()); 1.1890 + } 1.1891 + break; 1.1892 + 1.1893 + case lir_cond_less: 1.1894 +#ifdef OPT_RANGECHECK 1.1895 + assert(!op->check(), "just check"); 1.1896 +#endif 1.1897 + // AT = 1 TRUE 1.1898 + if (Assembler::is_simm16(temp_value)) { 1.1899 + __ slti(AT, reg_op1, temp_value); 1.1900 + } else { 1.1901 + __ move(AT, temp_value); 1.1902 + __ slt(AT, reg_op1, AT); 1.1903 + } 1.1904 + __ bne_far(AT, R0, *op->label()); 1.1905 + break; 1.1906 + 1.1907 + case lir_cond_lessEqual: 1.1908 +#ifdef OPT_RANGECHECK 1.1909 + assert(!op->check(), "just check"); 1.1910 +#endif 1.1911 + // AT = 0 TRUE 1.1912 + __ li(AT, temp_value); 1.1913 + __ slt(AT, AT, reg_op1); 1.1914 + __ beq(AT, R0, *op->label()); 1.1915 + break; 1.1916 + 1.1917 + case lir_cond_belowEqual: 1.1918 + // AT = 0 TRUE 1.1919 +#ifdef OPT_RANGECHECK 1.1920 + if (op->check()) { 1.1921 + __ li(AT, temp_value); 1.1922 + add_debug_info_for_range_check_here(op->info(), temp_value); 1.1923 + __ tgeu(AT, reg_op1, 29); 1.1924 + } else { 1.1925 +#endif 1.1926 + __ li(AT, temp_value); 1.1927 + __ sltu(AT, AT, reg_op1); 1.1928 + __ beq(AT, R0, *op->label()); 1.1929 +#ifdef OPT_RANGECHECK 1.1930 + } 1.1931 +#endif 1.1932 + break; 1.1933 + 1.1934 + case lir_cond_greaterEqual: 1.1935 +#ifdef OPT_RANGECHECK 1.1936 + assert(!op->check(), "just check"); 1.1937 +#endif 1.1938 + // AT = 0 TRUE 1.1939 + if (Assembler::is_simm16(temp_value)) { 1.1940 + __ slti(AT, reg_op1, temp_value); 1.1941 + } else { 1.1942 + __ li(AT, temp_value); 1.1943 + __ slt(AT, reg_op1, AT); 1.1944 + } 1.1945 + __ beq(AT, R0, *op->label()); 1.1946 + break; 1.1947 + 1.1948 + case lir_cond_aboveEqual: 1.1949 +#ifdef OPT_RANGECHECK 1.1950 + assert(!op->check(), "just check"); 1.1951 +#endif 1.1952 + // AT = 0 TRUE 1.1953 + if (Assembler::is_simm16(temp_value)) { 1.1954 + __ sltiu(AT, reg_op1, temp_value); 1.1955 + } else { 1.1956 + __ li(AT, temp_value); 1.1957 + __ sltu(AT, reg_op1, AT); 1.1958 + } 1.1959 + __ beq(AT, R0, *op->label()); 1.1960 + break; 1.1961 + 1.1962 + case lir_cond_greater: 1.1963 +#ifdef OPT_RANGECHECK 1.1964 + assert(!op->check(), "just check"); 1.1965 +#endif 1.1966 + // AT = 1 TRUE 1.1967 + __ li(AT, temp_value); 1.1968 + __ slt(AT, AT, reg_op1); 1.1969 + __ bne_far(AT, R0, *op->label()); 1.1970 + break; 1.1971 + 1.1972 + default: ShouldNotReachHere(); 1.1973 + } 1.1974 + 1.1975 + } else { 1.1976 + if (opr2->is_address()) { 1.1977 + //FIXME. aoqi lw or ld_ptr? 1.1978 + if (op->type() == T_INT) 1.1979 + __ lw(AT, as_Address(opr2->pointer()->as_address())); 1.1980 + else 1.1981 + __ ld_ptr(AT, as_Address(opr2->pointer()->as_address())); 1.1982 + } else if (opr2->is_stack()) { 1.1983 + //FIXME. aoqi 1.1984 + __ ld_ptr(AT, frame_map()->address_for_slot(opr2->single_stack_ix())); 1.1985 + } else { 1.1986 + ShouldNotReachHere(); 1.1987 + } 1.1988 + switch (condition) { 1.1989 + case lir_cond_equal: 1.1990 +#ifdef OPT_RANGECHECK 1.1991 + assert(!op->check(), "just check"); 1.1992 +#endif 1.1993 + __ beq(reg_op1, AT, *op->label()); 1.1994 + break; 1.1995 + case lir_cond_notEqual: 1.1996 +#ifdef OPT_RANGECHECK 1.1997 + assert(!op->check(), "just check"); 1.1998 +#endif 1.1999 + __ bne_far(reg_op1, AT, *op->label()); 1.2000 + break; 1.2001 + case lir_cond_less: 1.2002 +#ifdef OPT_RANGECHECK 1.2003 + assert(!op->check(), "just check"); 1.2004 +#endif 1.2005 + // AT = 1 TRUE 1.2006 + __ slt(AT, reg_op1, AT); 1.2007 + __ bne_far(AT, R0, *op->label()); 1.2008 + break; 1.2009 + case lir_cond_lessEqual: 1.2010 +#ifdef OPT_RANGECHECK 1.2011 + assert(!op->check(), "just check"); 1.2012 +#endif 1.2013 + // AT = 0 TRUE 1.2014 + __ slt(AT, AT, reg_op1); 1.2015 + __ beq(AT, R0, *op->label()); 1.2016 + break; 1.2017 + case lir_cond_belowEqual: 1.2018 +#ifdef OPT_RANGECHECK 1.2019 + assert(!op->check(), "just check"); 1.2020 +#endif 1.2021 + // AT = 0 TRUE 1.2022 + __ sltu(AT, AT, reg_op1); 1.2023 + __ beq(AT, R0, *op->label()); 1.2024 + break; 1.2025 + case lir_cond_greaterEqual: 1.2026 +#ifdef OPT_RANGECHECK 1.2027 + assert(!op->check(), "just check"); 1.2028 +#endif 1.2029 + // AT = 0 TRUE 1.2030 + __ slt(AT, reg_op1, AT); 1.2031 + __ beq(AT, R0, *op->label()); 1.2032 + break; 1.2033 + case lir_cond_aboveEqual: 1.2034 + // AT = 0 TRUE 1.2035 +#ifdef OPT_RANGECHECK 1.2036 + if (op->check()) { 1.2037 + add_debug_info_for_range_check_here(op->info(), opr1->rinfo()); 1.2038 + __ tgeu(reg_op1, AT, 29); 1.2039 + } else { 1.2040 +#endif 1.2041 + __ sltu(AT, reg_op1, AT); 1.2042 + __ beq_far(AT, R0, *op->label()); 1.2043 +#ifdef OPT_RANGECHECK 1.2044 + } 1.2045 +#endif 1.2046 + break; 1.2047 + case lir_cond_greater: 1.2048 +#ifdef OPT_RANGECHECK 1.2049 + assert(!op->check(), "just check"); 1.2050 +#endif 1.2051 + // AT = 1 TRUE 1.2052 + __ slt(AT, AT, reg_op1); 1.2053 + __ bne_far(AT, R0, *op->label()); 1.2054 + break; 1.2055 + default: ShouldNotReachHere(); 1.2056 + } 1.2057 + } 1.2058 +#ifdef OPT_RANGECHECK 1.2059 + if (!op->check()) 1.2060 +#endif 1.2061 + __ delayed()->nop(); 1.2062 + 1.2063 + } else if(opr1->is_address() || opr1->is_stack()) { 1.2064 +#ifdef OPT_RANGECHECK 1.2065 + assert(!op->check(), "just check"); 1.2066 +#endif 1.2067 + if (opr2->is_constant()) { 1.2068 + NOT_LP64(jint) LP64_ONLY(jlong) temp_value; 1.2069 + if (opr2->as_constant_ptr()->type() == T_INT) { 1.2070 + temp_value = (jint)opr2->as_constant_ptr()->as_jint(); 1.2071 + } else if (opr2->as_constant_ptr()->type() == T_OBJECT) { 1.2072 + temp_value = NOT_LP64((jint)) LP64_ONLY((jlong))(opr2->as_constant_ptr()->as_jobject()); 1.2073 + } else { 1.2074 + ShouldNotReachHere(); 1.2075 + } 1.2076 + 1.2077 + if (Assembler::is_simm16(temp_value)) { 1.2078 + if (opr1->is_address()) { 1.2079 + __ lw(AT, as_Address(opr1->pointer()->as_address())); 1.2080 + } else { 1.2081 + __ lw(AT, frame_map()->address_for_slot(opr1->single_stack_ix())); 1.2082 + } 1.2083 + 1.2084 + switch(condition) { 1.2085 + 1.2086 + case lir_cond_equal: 1.2087 + __ addi(AT, AT, -(int)temp_value); 1.2088 + __ beq(AT, R0, *op->label()); 1.2089 + break; 1.2090 + case lir_cond_notEqual: 1.2091 + __ addi(AT, AT, -(int)temp_value); 1.2092 + __ bne_far(AT, R0, *op->label()); 1.2093 + break; 1.2094 + case lir_cond_less: 1.2095 + // AT = 1 TRUE 1.2096 + __ slti(AT, AT, temp_value); 1.2097 + __ bne_far(AT, R0, *op->label()); 1.2098 + break; 1.2099 + case lir_cond_lessEqual: 1.2100 + // AT = 0 TRUE 1.2101 + __ addi(AT, AT, -temp_value); 1.2102 + __ slt(AT, R0, AT); 1.2103 + __ beq(AT, R0, *op->label()); 1.2104 + break; 1.2105 + case lir_cond_belowEqual: 1.2106 + // AT = 0 TRUE 1.2107 + __ addiu(AT, AT, -temp_value); 1.2108 + __ sltu(AT, R0, AT); 1.2109 + __ beq(AT, R0, *op->label()); 1.2110 + break; 1.2111 + case lir_cond_greaterEqual: 1.2112 + // AT = 0 TRUE 1.2113 + __ slti(AT, AT, temp_value); 1.2114 + __ beq(AT, R0, *op->label()); 1.2115 + break; 1.2116 + case lir_cond_aboveEqual: 1.2117 + // AT = 0 TRUE 1.2118 + __ sltiu(AT, AT, temp_value); 1.2119 + __ beq(AT, R0, *op->label()); 1.2120 + break; 1.2121 + case lir_cond_greater: 1.2122 + // AT = 1 TRUE 1.2123 + __ addi(AT, AT, -temp_value); 1.2124 + __ slt(AT, R0, AT); 1.2125 + __ bne_far(AT, R0, *op->label()); 1.2126 + break; 1.2127 + 1.2128 + default: 1.2129 + Unimplemented(); 1.2130 + } 1.2131 + } else { 1.2132 + Unimplemented(); 1.2133 + } 1.2134 + } else { 1.2135 + Unimplemented(); 1.2136 + } 1.2137 + __ delayed()->nop(); 1.2138 + 1.2139 + } else if(opr1->is_double_cpu()) { 1.2140 +#ifdef OPT_RANGECHECK 1.2141 + assert(!op->check(), "just check"); 1.2142 +#endif 1.2143 + Register opr1_lo = opr1->as_register_lo(); 1.2144 + Register opr1_hi = opr1->as_register_hi(); 1.2145 + 1.2146 + if (opr2->is_double_cpu()) { 1.2147 + Register opr2_lo = opr2->as_register_lo(); 1.2148 + Register opr2_hi = opr2->as_register_hi(); 1.2149 + switch (condition) { 1.2150 + case lir_cond_equal: { 1.2151 + Label L; 1.2152 +#ifndef _LP64 1.2153 + __ bne(opr1_lo, opr2_lo, L); 1.2154 + __ delayed()->nop(); 1.2155 + __ beq(opr1_hi, opr2_hi, *op->label()); 1.2156 +#else 1.2157 +/* static jobject java.lang.Long.toString(jlong) 1.2158 + 1.2159 + 10 move [t0t0|J] [a4a4|J] 1.2160 + 12 move [lng:-9223372036854775808|J] [a6a6|J] 1.2161 + 14 branch [EQ] [a4a4|J] [a6a6|J] [B1] 1.2162 + 0x000000555e8532e4: bne a4, a6, 0x000000555e8532e4 <-- error 1.2163 + 0x000000555e8532e8: sll zero, zero, 0 1.2164 +*/ 1.2165 + // __ beq(opr1_lo, opr2_lo, *op->label()); 1.2166 + __ beq(opr1_lo, opr2_lo, *op->label()); 1.2167 +#endif 1.2168 + __ delayed()->nop(); 1.2169 + __ bind(L); 1.2170 + } 1.2171 + break; 1.2172 + 1.2173 + case lir_cond_notEqual: 1.2174 + if (op->label()==NULL) 1.2175 + __ bne(opr1_lo, opr2_lo, *op->label());//by liaobin2 1.2176 + else 1.2177 + __ bne_far(opr1_lo, opr2_lo, *op->label());//by liaobin2 1.2178 + __ delayed()->nop(); 1.2179 + if (op->label()==NULL) 1.2180 + NOT_LP64(__ bne(opr1_hi, opr2_hi, *op->label()));//by liaobin3 1.2181 + else 1.2182 + NOT_LP64(__ bne_far(opr1_hi, opr2_hi, *op->label()));//by liaobin3 1.2183 + NOT_LP64(__ delayed()->nop()); 1.2184 + break; 1.2185 + 1.2186 + case lir_cond_less: { 1.2187 +#ifdef _LP64 1.2188 + __ slt(AT, opr1_lo, opr2_lo); 1.2189 + __ bne_far(AT, R0, *op->label()); 1.2190 + __ delayed()->nop(); 1.2191 +#else 1.2192 + Label L; 1.2193 + 1.2194 + // if hi less then jump 1.2195 + __ slt(AT, opr1_hi, opr2_hi); 1.2196 + __ bne(AT, R0, *op->label()); 1.2197 + __ delayed()->nop(); 1.2198 + 1.2199 + // if hi great then fail 1.2200 + __ bne(opr1_hi, opr2_hi, L); 1.2201 + __ delayed(); 1.2202 + 1.2203 + // now just comp lo as unsigned 1.2204 + __ sltu(AT, opr1_lo, opr2_lo); 1.2205 + __ bne_far(AT, R0, *op->label()); 1.2206 + __ delayed()->nop(); 1.2207 + 1.2208 + __ bind(L); 1.2209 +#endif 1.2210 + } 1.2211 + break; 1.2212 + 1.2213 + case lir_cond_lessEqual: { 1.2214 +#ifdef _LP64 1.2215 + __ slt(AT, opr2_lo, opr1_lo); 1.2216 + __ beq_far(AT, R0, *op->label()); 1.2217 + __ delayed()->nop(); 1.2218 +#else 1.2219 + Label L; 1.2220 + 1.2221 + // if hi great then fail 1.2222 + __ slt(AT, opr2_hi, opr1_hi); 1.2223 + __ bne(AT, R0, L); 1.2224 + __ delayed()->nop(); 1.2225 + 1.2226 + // if hi less then jump 1.2227 + if(op->label()==NULL) 1.2228 + __ bne(opr2_hi, opr1_hi, *op->label());//by liaobin4 1.2229 + else 1.2230 + __ bne_far(opr2_hi, opr1_hi, *op->label());//by liaobin4 1.2231 + __ delayed(); 1.2232 + 1.2233 + // now just comp lo as unsigned 1.2234 + __ sltu(AT, opr2_lo, opr1_lo); 1.2235 + __ beq(AT, R0, *op->label()); 1.2236 + __ delayed()->nop(); 1.2237 + 1.2238 + __ bind(L); 1.2239 +#endif 1.2240 + } 1.2241 + break; 1.2242 + 1.2243 + case lir_cond_belowEqual: { 1.2244 +#ifdef _LP64 1.2245 + __ sltu(AT, opr2_lo, opr1_lo); 1.2246 + __ beq(AT, R0, *op->label()); 1.2247 + __ delayed()->nop(); 1.2248 +#else 1.2249 + Label L; 1.2250 + 1.2251 + // if hi great then fail 1.2252 + __ sltu(AT, opr2_hi, opr1_hi); 1.2253 + __ bne_far(AT, R0, L); 1.2254 + __ delayed()->nop(); 1.2255 + 1.2256 + // if hi less then jump 1.2257 + if(op->label()==NULL) 1.2258 + __ bne(opr2_hi, opr1_hi, *op->label());//by liaobin5 1.2259 + else 1.2260 + __ bne_far(opr2_hi, opr1_hi, *op->label());//by liaobin5 1.2261 + __ delayed(); 1.2262 + 1.2263 + // now just comp lo as unsigned 1.2264 + __ sltu(AT, opr2_lo, opr1_lo); 1.2265 + __ beq(AT, R0, *op->label()); 1.2266 + __ delayed()->nop(); 1.2267 + 1.2268 + __ bind(L); 1.2269 +#endif 1.2270 + } 1.2271 + break; 1.2272 + 1.2273 + case lir_cond_greaterEqual: { 1.2274 +#ifdef _LP64 1.2275 + __ slt(AT, opr1_lo, opr2_lo); 1.2276 + __ beq_far(AT, R0, *op->label()); 1.2277 + __ delayed()->nop(); 1.2278 +#else 1.2279 + Label L; 1.2280 + 1.2281 + // if hi less then fail 1.2282 + __ slt(AT, opr1_hi, opr2_hi); 1.2283 + __ bne_far(AT, R0, L); 1.2284 + __ delayed()->nop(); 1.2285 + 1.2286 + // if hi great then jump 1.2287 + if(op->label()==NULL) 1.2288 + __ bne(opr2_hi, opr1_hi, *op->label());//by liaobin6 1.2289 + else 1.2290 + __ bne_far(opr2_hi, opr1_hi, *op->label());//by liaobin6 1.2291 + __ delayed(); 1.2292 + 1.2293 + // now just comp lo as unsigned 1.2294 + __ sltu(AT, opr1_lo, opr2_lo); 1.2295 + __ beq(AT, R0, *op->label()); 1.2296 + __ delayed()->nop(); 1.2297 + 1.2298 + __ bind(L); 1.2299 +#endif 1.2300 + } 1.2301 + break; 1.2302 + 1.2303 + case lir_cond_aboveEqual: { 1.2304 +#ifdef _LP64 1.2305 + __ sltu(AT, opr1_lo, opr2_lo); 1.2306 + __ beq_far(AT, R0, *op->label()); 1.2307 + __ delayed()->nop(); 1.2308 +#else 1.2309 + Label L; 1.2310 + 1.2311 + // if hi less then fail 1.2312 + __ sltu(AT, opr1_hi, opr2_hi); 1.2313 + __ bne(AT, R0, L); 1.2314 + __ delayed()->nop(); 1.2315 + 1.2316 + // if hi great then jump 1.2317 + if(op->label()==NULL) 1.2318 + __ bne(opr2_hi, opr1_hi, *op->label());//by liaobin7 1.2319 + else 1.2320 + __ bne_far(opr2_hi, opr1_hi, *op->label());//by liaobin7 1.2321 + __ delayed(); 1.2322 + 1.2323 + // now just comp lo as unsigned 1.2324 + __ sltu(AT, opr1_lo, opr2_lo); 1.2325 + __ beq(AT, R0, *op->label()); 1.2326 + __ delayed()->nop(); 1.2327 + 1.2328 + __ bind(L); 1.2329 +#endif 1.2330 + } 1.2331 + break; 1.2332 + 1.2333 + case lir_cond_greater: { 1.2334 +#ifdef _LP64 1.2335 + __ slt(AT, opr2_lo, opr1_lo); 1.2336 + __ bne_far(AT, R0, *op->label()); 1.2337 + __ delayed()->nop(); 1.2338 +#else 1.2339 + Label L; 1.2340 + 1.2341 + // if hi great then jump 1.2342 + __ slt(AT, opr2_hi, opr1_hi); 1.2343 + __ bne(AT, R0, *op->label()); 1.2344 + __ delayed()->nop(); 1.2345 + 1.2346 + // if hi less then fail 1.2347 + __ bne(opr2_hi, opr1_hi, L); 1.2348 + __ delayed(); 1.2349 + 1.2350 + // now just comp lo as unsigned 1.2351 + __ sltu(AT, opr2_lo, opr1_lo); 1.2352 + __ bne(AT, R0, *op->label()); 1.2353 + __ delayed()->nop(); 1.2354 + 1.2355 + __ bind(L); 1.2356 +#endif 1.2357 + } 1.2358 + break; 1.2359 + 1.2360 + default: ShouldNotReachHere(); 1.2361 + } 1.2362 + 1.2363 + } else if(opr2->is_constant()) { 1.2364 + jlong lv = opr2->as_jlong(); 1.2365 +#ifndef _LP64 1.2366 + jint iv_lo = (jint)lv; 1.2367 + jint iv_hi = (jint)(lv>>32); 1.2368 + bool is_zero = (lv==0); 1.2369 +#endif 1.2370 + 1.2371 + switch (condition) { 1.2372 + case lir_cond_equal: 1.2373 +#ifdef _LP64 1.2374 + __ li(T8, lv); 1.2375 + __ beq(opr1_lo, T8, *op->label()); 1.2376 + __ delayed()->nop(); 1.2377 +#else 1.2378 + if (is_zero) { 1.2379 + __ orr(AT, opr1_lo, opr1_hi); 1.2380 + __ beq(AT, R0, *op->label()); 1.2381 + __ delayed()->nop(); 1.2382 + } else { 1.2383 + Label L; 1.2384 + __ move(T8, iv_lo); 1.2385 + __ bne(opr1_lo, T8, L); 1.2386 + __ delayed(); 1.2387 + __ move(T8, iv_hi); 1.2388 + __ beq(opr1_hi, T8, *op->label()); 1.2389 + __ delayed()->nop(); 1.2390 + __ bind(L); 1.2391 + } 1.2392 +#endif 1.2393 + break; 1.2394 + 1.2395 + case lir_cond_notEqual: 1.2396 +#ifdef _LP64 1.2397 + __ li(T8, lv); 1.2398 + __ bne(opr1_lo, T8, *op->label()); 1.2399 + __ delayed()->nop(); 1.2400 +#else 1.2401 + if (is_zero) { 1.2402 + __ orr(AT, opr1_lo, opr1_hi); 1.2403 + __ bne(AT, R0, *op->label()); 1.2404 + __ delayed()->nop(); 1.2405 + } else { 1.2406 + __ move(T8, iv_lo); 1.2407 + __ bne(opr1_lo, T8, *op->label()); 1.2408 + __ delayed(); 1.2409 + __ move(T8, iv_hi); 1.2410 + __ bne(opr1_hi, T8, *op->label()); 1.2411 + __ delayed()->nop(); 1.2412 + } 1.2413 +#endif 1.2414 + break; 1.2415 + 1.2416 + case lir_cond_less: 1.2417 +#ifdef _LP64 1.2418 + __ li(T8, lv); 1.2419 + __ slt(AT, opr1_lo, T8); 1.2420 + __ bne_far(AT, R0, *op->label()); 1.2421 + __ delayed()->nop(); 1.2422 +#else 1.2423 + if (is_zero) { 1.2424 + __ bltz(opr1_hi, *op->label()); 1.2425 + __ bltz(opr1_lo, *op->label()); 1.2426 + __ delayed()->nop(); 1.2427 + } else { 1.2428 + Label L; 1.2429 + 1.2430 + // if hi less then jump 1.2431 + __ move(T8, iv_hi); 1.2432 + __ slt(AT, opr1_hi, T8); 1.2433 + __ bne_far(AT, R0, *op->label()); 1.2434 + __ delayed()->nop(); 1.2435 + 1.2436 + // if hi great then fail 1.2437 + __ bne(opr1_hi, T8, L); 1.2438 + __ delayed(); 1.2439 + 1.2440 + // now just comp lo as unsigned 1.2441 + if (Assembler::is_simm16(iv_lo)) { 1.2442 + __ sltiu(AT, opr1_lo, iv_lo); 1.2443 + } else { 1.2444 + __ move(T8, iv_lo); 1.2445 + __ sltu(AT, opr1_lo, T8); 1.2446 + } 1.2447 + __ bne(AT, R0, *op->label()); 1.2448 + __ delayed()->nop(); 1.2449 + 1.2450 + __ bind(L); 1.2451 + } 1.2452 +#endif 1.2453 + break; 1.2454 + 1.2455 + case lir_cond_lessEqual: 1.2456 +#ifdef _LP64 1.2457 + __ li(T8, lv); 1.2458 + __ slt(AT, T8, opr1_lo); 1.2459 + __ beq(AT, R0, *op->label()); 1.2460 + __ delayed()->nop(); 1.2461 +#else 1.2462 + if (is_zero) { 1.2463 + __ bltz(opr1_hi, *op->label()); 1.2464 + __ delayed()->nop(); 1.2465 + __ orr(AT, opr1_hi, opr1_lo); 1.2466 + __ beq(AT, R0, *op->label()); 1.2467 + __ delayed(); 1.2468 + } else { 1.2469 + Label L; 1.2470 + 1.2471 + // if hi great then fail 1.2472 + __ move(T8, iv_hi); 1.2473 + __ slt(AT, T8, opr1_hi); 1.2474 + __ bne(AT, R0, L); 1.2475 + __ delayed()->nop(); 1.2476 + 1.2477 + // if hi less then jump 1.2478 + __ bne(T8, opr1_hi, *op->label()); 1.2479 + __ delayed(); 1.2480 + 1.2481 + // now just comp lo as unsigned 1.2482 + __ move(T8, iv_lo); 1.2483 + __ sltu(AT, T8, opr1_lo); 1.2484 + __ beq(AT, R0, *op->label()); 1.2485 + __ delayed()->nop(); 1.2486 + 1.2487 + __ bind(L); 1.2488 + } 1.2489 +#endif 1.2490 + break; 1.2491 + 1.2492 + case lir_cond_belowEqual: 1.2493 +#ifdef _LP64 1.2494 + __ li(T8, lv); 1.2495 + __ sltu(AT, T8, opr1_lo); 1.2496 + __ beq(AT, R0, *op->label()); 1.2497 + __ delayed()->nop(); 1.2498 +#else 1.2499 + if (is_zero) { 1.2500 + __ orr(AT, opr1_hi, opr1_lo); 1.2501 + __ beq(AT, R0, *op->label()); 1.2502 + __ delayed()->nop(); 1.2503 + } else { 1.2504 + Label L; 1.2505 + 1.2506 + // if hi great then fail 1.2507 + __ move(T8, iv_hi); 1.2508 + __ sltu(AT, T8, opr1_hi); 1.2509 + __ bne(AT, R0, L); 1.2510 + __ delayed()->nop(); 1.2511 + 1.2512 + // if hi less then jump 1.2513 + __ bne(T8, opr1_hi, *op->label()); 1.2514 + __ delayed(); 1.2515 + 1.2516 + // now just comp lo as unsigned 1.2517 + __ move(T8, iv_lo); 1.2518 + __ sltu(AT, T8, opr1_lo); 1.2519 + __ beq(AT, R0, *op->label()); 1.2520 + __ delayed()->nop(); 1.2521 + 1.2522 + __ bind(L); 1.2523 + } 1.2524 +#endif 1.2525 + break; 1.2526 + 1.2527 + case lir_cond_greaterEqual: 1.2528 +#ifdef _LP64 1.2529 + __ li(T8, lv); 1.2530 + __ slt(AT, opr1_lo, T8); 1.2531 + __ beq(AT, R0, *op->label()); 1.2532 + __ delayed()->nop(); 1.2533 +#else 1.2534 + if (is_zero) { 1.2535 + __ bgez(opr1_hi, *op->label()); 1.2536 + __ delayed()->nop(); 1.2537 + } else { 1.2538 + Label L; 1.2539 + 1.2540 + // if hi less then fail 1.2541 + __ move(T8, iv_hi); 1.2542 + __ slt(AT, opr1_hi, T8); 1.2543 + __ bne(AT, R0, L); 1.2544 + __ delayed()->nop(); 1.2545 + 1.2546 + // if hi great then jump 1.2547 + __ bne(T8, opr1_hi, *op->label()); 1.2548 + __ delayed(); 1.2549 + 1.2550 + // now just comp lo as unsigned 1.2551 + if (Assembler::is_simm16(iv_lo)) { 1.2552 + __ sltiu(AT, opr1_lo, iv_lo); 1.2553 + } else { 1.2554 + __ move(T8, iv_lo); 1.2555 + __ sltu(AT, opr1_lo, T8); 1.2556 + } 1.2557 + __ beq(AT, R0, *op->label()); 1.2558 + __ delayed()->nop(); 1.2559 + 1.2560 + __ bind(L); 1.2561 + } 1.2562 +#endif 1.2563 + break; 1.2564 + 1.2565 + case lir_cond_aboveEqual: 1.2566 +#ifdef _LP64 1.2567 + __ li(T8, lv); 1.2568 + __ sltu(AT, opr1_lo, T8); 1.2569 + __ beq(AT, R0, *op->label()); 1.2570 + __ delayed()->nop(); 1.2571 +#else 1.2572 + if (is_zero) { 1.2573 + if(op->label()==NULL) //by liaob2 1.2574 + __ b(*op->label()); 1.2575 + else 1.2576 + __ b_far(*op->label()); 1.2577 + __ delayed()->nop(); 1.2578 + } else { 1.2579 + Label L; 1.2580 + 1.2581 + // if hi less then fail 1.2582 + __ move(T8, iv_hi); 1.2583 + __ sltu(AT, opr1_hi, T8); 1.2584 + __ bne(AT, R0, L); 1.2585 + __ delayed()->nop(); 1.2586 + 1.2587 + // if hi great then jump 1.2588 + __ bne(T8, opr1_hi, *op->label()); 1.2589 + __ delayed(); 1.2590 + 1.2591 + // now just comp lo as unsigned 1.2592 + if (Assembler::is_simm16(iv_lo)) { 1.2593 + __ sltiu(AT, opr1_lo, iv_lo); 1.2594 + } else { 1.2595 + __ move(T8, iv_lo); 1.2596 + __ sltu(AT, opr1_lo, T8); 1.2597 + } 1.2598 + __ beq(AT, R0, *op->label()); 1.2599 + __ delayed()->nop(); 1.2600 + 1.2601 + __ bind(L); 1.2602 + } 1.2603 +#endif 1.2604 + break; 1.2605 + 1.2606 + case lir_cond_greater: 1.2607 +#ifdef _LP64 1.2608 + __ li(T8, lv); 1.2609 + __ slt(AT, T8, opr1_lo); 1.2610 + __ bne_far(AT, R0, *op->label()); 1.2611 + __ delayed()->nop(); 1.2612 +#else 1.2613 + if (is_zero) { 1.2614 + Label L; 1.2615 + __ bgtz(opr1_hi, *op->label()); 1.2616 + __ delayed()->nop(); 1.2617 + __ bne(opr1_hi, R0, L); 1.2618 + __ delayed()->nop(); 1.2619 + __ bne(opr1_lo, R0, *op->label()); 1.2620 + __ delayed()->nop(); 1.2621 + __ bind(L); 1.2622 + } else { 1.2623 + Label L; 1.2624 + 1.2625 + // if hi great then jump 1.2626 + __ move(T8, iv_hi); 1.2627 + __ slt(AT, T8, opr1_hi); 1.2628 + __ bne(AT, R0, *op->label()); 1.2629 + __ delayed()->nop(); 1.2630 + 1.2631 + // if hi less then fail 1.2632 + __ bne(T8, opr1_hi, L); 1.2633 + __ delayed(); 1.2634 + 1.2635 + // now just comp lo as unsigned 1.2636 + __ move(T8, iv_lo); 1.2637 + __ sltu(AT, T8, opr1_lo); 1.2638 + __ bne(AT, R0, *op->label()); 1.2639 + __ delayed()->nop(); 1.2640 + 1.2641 + __ bind(L); 1.2642 + } 1.2643 +#endif 1.2644 + break; 1.2645 + 1.2646 + default: 1.2647 + ShouldNotReachHere(); 1.2648 + } 1.2649 + } else { 1.2650 + Unimplemented(); 1.2651 + } 1.2652 + } else if (opr1->is_single_fpu()) { 1.2653 +#ifdef OPT_RANGECHECK 1.2654 + assert(!op->check(), "just check"); 1.2655 +#endif 1.2656 + assert(opr2->is_single_fpu(), "change the code"); 1.2657 + 1.2658 + FloatRegister reg_op1 = opr1->as_float_reg(); 1.2659 + FloatRegister reg_op2 = opr2->as_float_reg(); 1.2660 + // bool un_ls 1.2661 + bool un_jump = (op->ublock()->label()==op->label()); 1.2662 + 1.2663 + Label& L = *op->label(); 1.2664 + 1.2665 + switch (condition) { 1.2666 + case lir_cond_equal: 1.2667 + if (un_jump) 1.2668 + __ c_ueq_s(reg_op1, reg_op2); 1.2669 + else 1.2670 + __ c_eq_s(reg_op1, reg_op2); 1.2671 + __ bc1t(L); 1.2672 + 1.2673 + break; 1.2674 + 1.2675 + case lir_cond_notEqual: 1.2676 + if (un_jump) 1.2677 + __ c_eq_s(reg_op1, reg_op2); 1.2678 + else 1.2679 + __ c_ueq_s(reg_op1, reg_op2); 1.2680 + __ bc1f(L); 1.2681 + 1.2682 + break; 1.2683 + 1.2684 + case lir_cond_less: 1.2685 + if (un_jump) 1.2686 + __ c_ult_s(reg_op1, reg_op2); 1.2687 + else 1.2688 + __ c_olt_s(reg_op1, reg_op2); 1.2689 + __ bc1t(L); 1.2690 + 1.2691 + break; 1.2692 + 1.2693 + case lir_cond_lessEqual: 1.2694 + case lir_cond_belowEqual: 1.2695 + if (un_jump) 1.2696 + __ c_ule_s(reg_op1, reg_op2); 1.2697 + else 1.2698 + __ c_ole_s(reg_op1, reg_op2); 1.2699 + __ bc1t(L); 1.2700 + 1.2701 + break; 1.2702 + 1.2703 + case lir_cond_greaterEqual: 1.2704 + case lir_cond_aboveEqual: 1.2705 + if (un_jump) 1.2706 + __ c_olt_s(reg_op1, reg_op2); 1.2707 + else 1.2708 + __ c_ult_s(reg_op1, reg_op2); 1.2709 + __ bc1f(L); 1.2710 + 1.2711 + break; 1.2712 + 1.2713 + case lir_cond_greater: 1.2714 + if (un_jump) 1.2715 + __ c_ole_s(reg_op1, reg_op2); 1.2716 + else 1.2717 + __ c_ule_s(reg_op1, reg_op2); 1.2718 + __ bc1f(L); 1.2719 + 1.2720 + break; 1.2721 + 1.2722 + default: 1.2723 + ShouldNotReachHere(); 1.2724 + } 1.2725 + __ delayed()->nop(); 1.2726 + } else if (opr1->is_double_fpu()) { 1.2727 +#ifdef OPT_RANGECHECK 1.2728 + assert(!op->check(), "just check"); 1.2729 +#endif 1.2730 + assert(opr2->is_double_fpu(), "change the code"); 1.2731 + 1.2732 + FloatRegister reg_op1 = opr1->as_double_reg(); 1.2733 + FloatRegister reg_op2 = opr2->as_double_reg(); 1.2734 + bool un_jump = (op->ublock()->label()==op->label()); 1.2735 + Label& L = *op->label(); 1.2736 + 1.2737 + switch (condition) { 1.2738 + case lir_cond_equal: 1.2739 + if (un_jump) 1.2740 + __ c_ueq_d(reg_op1, reg_op2); 1.2741 + else 1.2742 + __ c_eq_d(reg_op1, reg_op2); 1.2743 + __ bc1t(L); 1.2744 + 1.2745 + break; 1.2746 + 1.2747 + case lir_cond_notEqual: 1.2748 + if (un_jump) 1.2749 + __ c_eq_d(reg_op1, reg_op2); 1.2750 + else 1.2751 + __ c_ueq_d(reg_op1, reg_op2); 1.2752 + __ bc1f(L); 1.2753 + 1.2754 + break; 1.2755 + 1.2756 + case lir_cond_less: 1.2757 + if (un_jump) 1.2758 + __ c_ult_d(reg_op1, reg_op2); 1.2759 + else 1.2760 + __ c_olt_d(reg_op1, reg_op2); 1.2761 + __ bc1t(L); 1.2762 + 1.2763 + break; 1.2764 + 1.2765 + case lir_cond_lessEqual: 1.2766 + case lir_cond_belowEqual: 1.2767 + if (un_jump) 1.2768 + __ c_ule_d(reg_op1, reg_op2); 1.2769 + else 1.2770 + __ c_ole_d(reg_op1, reg_op2); 1.2771 + __ bc1t(L); 1.2772 + 1.2773 + break; 1.2774 + 1.2775 + case lir_cond_greaterEqual: 1.2776 + case lir_cond_aboveEqual: 1.2777 + if (un_jump) 1.2778 + __ c_olt_d(reg_op1, reg_op2); 1.2779 + else 1.2780 + __ c_ult_d(reg_op1, reg_op2); 1.2781 + __ bc1f(L); 1.2782 + 1.2783 + break; 1.2784 + 1.2785 + case lir_cond_greater: 1.2786 + if (un_jump) 1.2787 + __ c_ole_d(reg_op1, reg_op2); 1.2788 + else 1.2789 + __ c_ule_d(reg_op1, reg_op2); 1.2790 + __ bc1f(L); 1.2791 + 1.2792 + break; 1.2793 + 1.2794 + default: 1.2795 + ShouldNotReachHere(); 1.2796 + } 1.2797 + __ delayed()->nop(); 1.2798 + } else { 1.2799 + Unimplemented(); 1.2800 + } 1.2801 +} 1.2802 + 1.2803 + 1.2804 +void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { 1.2805 + LIR_Opr value = op->in_opr(); 1.2806 + LIR_Opr src = op->in_opr(); 1.2807 + LIR_Opr dest = op->result_opr(); 1.2808 + Bytecodes::Code code = op->bytecode(); 1.2809 + 1.2810 + switch (code) { 1.2811 + case Bytecodes::_i2l: 1.2812 + move_regs(src->as_register(), dest->as_register_lo()); 1.2813 + NOT_LP64(__ sra (dest->as_register_hi(), dest->as_register_lo(), 31)); 1.2814 + break; 1.2815 + 1.2816 + case Bytecodes::_l2i: 1.2817 +#ifndef _LP64 1.2818 + move_regs (src->as_register_lo(), dest->as_register()); 1.2819 +#else 1.2820 + __ dsll32(dest->as_register(), src->as_register_lo(), 0); 1.2821 + __ dsra32(dest->as_register(), dest->as_register(), 0); 1.2822 +#endif 1.2823 + break; 1.2824 + 1.2825 + case Bytecodes::_i2b: 1.2826 +#ifndef _LP64 1.2827 + move_regs (src->as_register(), dest->as_register()); 1.2828 + __ sign_extend_byte(dest->as_register()); 1.2829 +#else 1.2830 + __ dsll32(dest->as_register(), src->as_register(), 24); 1.2831 + __ dsra32(dest->as_register(), dest->as_register(), 24); 1.2832 +#endif 1.2833 + break; 1.2834 + 1.2835 + case Bytecodes::_i2c: 1.2836 + __ andi(dest->as_register(), src->as_register(), 0xFFFF); 1.2837 + break; 1.2838 + 1.2839 + case Bytecodes::_i2s: 1.2840 +#ifndef _LP64 1.2841 + move_regs (src->as_register(), dest->as_register()); 1.2842 + __ sign_extend_short(dest->as_register()); 1.2843 +#else 1.2844 + __ dsll32(dest->as_register(), src->as_register(), 16); 1.2845 + __ dsra32(dest->as_register(), dest->as_register(), 16); 1.2846 +#endif 1.2847 + break; 1.2848 + 1.2849 + case Bytecodes::_f2d: 1.2850 + __ cvt_d_s(dest->as_double_reg(), src->as_float_reg()); 1.2851 + break; 1.2852 + 1.2853 + case Bytecodes::_d2f: 1.2854 + __ cvt_s_d(dest->as_float_reg(), src->as_double_reg()); 1.2855 + break; 1.2856 + case Bytecodes::_i2f: { 1.2857 + FloatRegister df = dest->as_float_reg(); 1.2858 + if(src->is_single_cpu()) { 1.2859 + __ mtc1(src->as_register(), df); 1.2860 + __ cvt_s_w(df, df); 1.2861 + } else if (src->is_stack()) { 1.2862 + Address src_addr = src->is_single_stack() 1.2863 + ? frame_map()->address_for_slot(src->single_stack_ix()) 1.2864 + : frame_map()->address_for_slot(src->double_stack_ix()); 1.2865 + __ lw(AT, src_addr); 1.2866 + __ mtc1(AT, df); 1.2867 + __ cvt_s_w(df, df); 1.2868 + } else { 1.2869 + Unimplemented(); 1.2870 + } 1.2871 + break; 1.2872 + } 1.2873 + case Bytecodes::_i2d: { 1.2874 + FloatRegister dd = dest->as_double_reg(); 1.2875 + if (src->is_single_cpu()) { 1.2876 + __ mtc1(src->as_register(), dd); 1.2877 + __ cvt_d_w(dd, dd); 1.2878 + } else if (src->is_stack()) { 1.2879 + Address src_addr = src->is_single_stack() 1.2880 + ? frame_map()->address_for_slot(value->single_stack_ix()) 1.2881 + : frame_map()->address_for_slot(value->double_stack_ix()); 1.2882 + __ lw(AT, src_addr); 1.2883 + __ mtc1(AT, dd); 1.2884 + __ cvt_d_w(dd, dd); 1.2885 + } else { 1.2886 + Unimplemented(); 1.2887 + } 1.2888 + break; 1.2889 + } 1.2890 + case Bytecodes::_f2i: { 1.2891 + FloatRegister fval = src->as_float_reg(); 1.2892 + Register dreg = dest->as_register(); 1.2893 + 1.2894 + Label L; 1.2895 + __ c_un_s(fval, fval); //NaN? 1.2896 + __ bc1t(L); 1.2897 + __ delayed(); 1.2898 + __ move(dreg, R0); 1.2899 + 1.2900 + __ trunc_w_s(F30, fval); 1.2901 + 1.2902 + /* Call SharedRuntime:f2i() to do valid convention */ 1.2903 + __ cfc1(AT, 31); 1.2904 + __ li(T9, 0x10000); 1.2905 + __ andr(AT, AT, T9); 1.2906 + __ beq(AT, R0, L); 1.2907 + __ delayed()->mfc1(dreg, F30); 1.2908 + 1.2909 + __ mov_s(F12, fval); 1.2910 + __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1); 1.2911 + __ move(dreg, V0); 1.2912 + __ bind(L); 1.2913 + break; 1.2914 + } 1.2915 + case Bytecodes::_d2i: { 1.2916 + FloatRegister dval = src->as_double_reg(); 1.2917 + Register dreg = dest->as_register(); 1.2918 + 1.2919 + Label L; 1.2920 +#ifndef _LP64 1.2921 + __ c_un_d(dval, dval); //NaN? 1.2922 + __ bc1t(L); 1.2923 + __ delayed(); 1.2924 + __ move(dreg, R0); 1.2925 +#endif 1.2926 + 1.2927 + __ trunc_w_d(F30, dval); 1.2928 + __ cfc1(AT, 31); 1.2929 + __ li(T9, 0x10000); 1.2930 + __ andr(AT, AT, T9); 1.2931 + __ beq(AT, R0, L); 1.2932 + __ delayed()->mfc1(dreg, F30); 1.2933 + 1.2934 + __ mov_d(F12, dval); 1.2935 + __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 1); 1.2936 + __ move(dreg, V0); 1.2937 + __ bind(L); 1.2938 + break; 1.2939 + } 1.2940 + case Bytecodes::_l2f: { 1.2941 + FloatRegister ldf = dest->as_float_reg(); 1.2942 + if (src->is_double_cpu()) { 1.2943 +#ifndef _LP64 1.2944 + __ mtc1(src->as_register_lo(), ldf); 1.2945 + __ mtc1(src->as_register_hi(), ldf + 1); 1.2946 + __ cvt_s_l(ldf, ldf); 1.2947 +#else 1.2948 + __ dmtc1(src->as_register_lo(), ldf); 1.2949 + __ cvt_s_l(ldf, ldf); 1.2950 +#endif 1.2951 + } else if (src->is_double_stack()) { 1.2952 + Address src_addr=frame_map()->address_for_slot(value->double_stack_ix()); 1.2953 +#ifndef _LP64 1.2954 + __ lw(AT, src_addr); 1.2955 + __ mtc1(AT, ldf); 1.2956 + __ lw(AT, src_addr.base(), src_addr.disp() + 4); 1.2957 + __ mtc1(AT, ldf + 1); 1.2958 + __ cvt_s_l(ldf, ldf); 1.2959 +#else 1.2960 + __ ld(AT, src_addr); 1.2961 + __ dmtc1(AT, ldf); 1.2962 + __ cvt_s_l(ldf, ldf); 1.2963 +#endif 1.2964 + } else { 1.2965 + Unimplemented(); 1.2966 + } 1.2967 + break; 1.2968 + } 1.2969 + case Bytecodes::_l2d: { 1.2970 + FloatRegister ldd = dest->as_double_reg(); 1.2971 + if (src->is_double_cpu()) { 1.2972 +#ifndef _LP64 1.2973 + __ mtc1(src->as_register_lo(), ldd); 1.2974 + __ mtc1(src->as_register_hi(), ldd + 1); 1.2975 + __ cvt_d_l(ldd, ldd); 1.2976 +#else 1.2977 + __ dmtc1(src->as_register_lo(), ldd); 1.2978 + __ cvt_d_l(ldd, ldd); 1.2979 +#endif 1.2980 + } else if (src->is_double_stack()) { 1.2981 + Address src_addr = frame_map()->address_for_slot(src->double_stack_ix()); 1.2982 +#ifndef _LP64 1.2983 + __ lw(AT, src_addr); 1.2984 + __ mtc1(AT, ldd); 1.2985 + __ lw(AT, src_addr.base(), src_addr.disp() + 4); 1.2986 + __ mtc1(AT, ldd + 1); 1.2987 + __ cvt_d_l(ldd, ldd); 1.2988 +#else 1.2989 + __ ld(AT, src_addr); 1.2990 + __ dmtc1(AT, ldd); 1.2991 + __ cvt_d_l(ldd, ldd); 1.2992 +#endif 1.2993 + } else { 1.2994 + Unimplemented(); 1.2995 + } 1.2996 + break; 1.2997 + } 1.2998 + 1.2999 + case Bytecodes::_f2l: { 1.3000 + FloatRegister fval = src->as_float_reg(); 1.3001 + Register dlo = dest->as_register_lo(); 1.3002 + Register dhi = dest->as_register_hi(); 1.3003 + 1.3004 + Label L; 1.3005 + __ move(dhi, R0); 1.3006 + __ c_un_s(fval, fval); //NaN? 1.3007 + __ bc1t(L); 1.3008 + __ delayed(); 1.3009 + __ move(dlo, R0); 1.3010 + 1.3011 + __ trunc_l_s(F30, fval); 1.3012 +#ifdef _LP64 1.3013 + __ cfc1(AT, 31); 1.3014 + __ li(T9, 0x10000); 1.3015 + __ andr(AT, AT, T9); 1.3016 + __ beq(AT, R0, L); 1.3017 + __ delayed()->dmfc1(dlo, F30); 1.3018 + 1.3019 + __ mov_s(F12, fval); 1.3020 + __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1); 1.3021 + __ move(dlo, V0); 1.3022 +#else 1.3023 + __ mfc1(dlo, F30); 1.3024 +#endif 1.3025 + NOT_LP64(__ mfc1(dhi, F31)); 1.3026 + __ bind(L); 1.3027 + break; 1.3028 + } 1.3029 + case Bytecodes::_d2l: { 1.3030 + FloatRegister dval = src->as_double_reg(); 1.3031 + Register dlo = dest->as_register_lo(); 1.3032 + Register dhi = dest->as_register_hi(); 1.3033 + 1.3034 + Label L; 1.3035 + __ move(dhi, R0); 1.3036 + __ c_un_d(dval, dval); //NaN? 1.3037 + __ bc1t(L); 1.3038 + __ delayed(); 1.3039 + __ move(dlo, R0); 1.3040 + 1.3041 + __ trunc_l_d(F30, dval); 1.3042 +#ifdef _LP64 1.3043 + __ cfc1(AT, 31); 1.3044 + __ li(T9, 0x10000); 1.3045 + __ andr(AT, AT, T9); 1.3046 + __ beq(AT, R0, L); 1.3047 + __ delayed()->dmfc1(dlo, F30); 1.3048 + 1.3049 + __ mov_d(F12, dval); 1.3050 + __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 1); 1.3051 + __ move(dlo, V0); 1.3052 +#else 1.3053 + __ mfc1(dlo, F30); 1.3054 + __ mfc1(dhi, F31); 1.3055 +#endif 1.3056 + __ bind(L); 1.3057 + break; 1.3058 + } 1.3059 + 1.3060 + default: ShouldNotReachHere(); 1.3061 + } 1.3062 +} 1.3063 + 1.3064 +void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) { 1.3065 + if (op->init_check()) { 1.3066 + add_debug_info_for_null_check_here(op->stub()->info()); 1.3067 + __ lw(AT,Address(op->klass()->as_register(), 1.3068 + InstanceKlass::init_state_offset())); 1.3069 + __ addi(AT, AT, -InstanceKlass::fully_initialized); 1.3070 + __ bne_far(AT, R0,*op->stub()->entry()); 1.3071 + __ delayed()->nop(); 1.3072 + } 1.3073 + __ allocate_object( 1.3074 + op->obj()->as_register(), 1.3075 + op->tmp1()->as_register(), 1.3076 + op->tmp2()->as_register(), 1.3077 + op->header_size(), 1.3078 + op->object_size(), 1.3079 + op->klass()->as_register(), 1.3080 + *op->stub()->entry()); 1.3081 + 1.3082 + __ bind(*op->stub()->continuation()); 1.3083 +} 1.3084 + 1.3085 +void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) { 1.3086 + if (UseSlowPath || 1.3087 + (!UseFastNewObjectArray && (op->type() == T_OBJECT || op->type() == T_ARRAY)) || 1.3088 + (!UseFastNewTypeArray && (op->type() != T_OBJECT && op->type() != T_ARRAY))) { 1.3089 + __ b_far(*op->stub()->entry()); 1.3090 + __ delayed()->nop(); 1.3091 + } else { 1.3092 + Register len = op->len()->as_register(); 1.3093 + Register tmp1 = op->tmp1()->as_register(); 1.3094 + Register tmp2 = op->tmp2()->as_register(); 1.3095 + Register tmp3 = op->tmp3()->as_register(); 1.3096 + __ allocate_array(op->obj()->as_register(), 1.3097 + len, 1.3098 + tmp1, 1.3099 + tmp2, 1.3100 + tmp3, 1.3101 + arrayOopDesc::header_size(op->type()), 1.3102 + array_element_size(op->type()), 1.3103 + op->klass()->as_register(), 1.3104 + *op->stub()->entry()); 1.3105 + } 1.3106 + __ bind(*op->stub()->continuation()); 1.3107 +} 1.3108 + 1.3109 + 1.3110 + 1.3111 +void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { 1.3112 + LIR_Code code = op->code(); 1.3113 +// if (code == lir_store_check) { 1.3114 + Register value = op->object()->as_register(); 1.3115 + Register array = op->array()->as_register(); 1.3116 + Register k_RInfo = op->tmp1()->as_register(); 1.3117 + Register klass_RInfo = op->tmp2()->as_register(); 1.3118 + Register tmp = op->tmp3()->as_register(); 1.3119 + 1.3120 + CodeStub* stub = op->stub(); 1.3121 + //check if it needs to be profiled 1.3122 + ciMethodData* md; 1.3123 + ciProfileData* data; 1.3124 + if (op->should_profile()) { 1.3125 + ciMethod* method = op->profiled_method(); 1.3126 + assert(method != NULL, "Should have method"); 1.3127 + int bci = op->profiled_bci(); 1.3128 + md = method->method_data_or_null(); 1.3129 + assert(md != NULL, "Sanity"); 1.3130 + data = md->bci_to_data(bci); 1.3131 + assert(data != NULL, "need data for type check"); 1.3132 + assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); 1.3133 + } 1.3134 + Label profile_cast_success, profile_cast_failure, done; 1.3135 + Label *success_target = op->should_profile() ? &profile_cast_success : &done; 1.3136 + Label *failure_target = op->should_profile() ? &profile_cast_failure : &done; 1.3137 + //__ cmpptr(value, (int32_t)NULL_WORD); 1.3138 + if(op->should_profile()) { 1.3139 + Label not_null; 1.3140 + __ bne(value, R0, not_null); 1.3141 + __ delayed()->nop(); 1.3142 + 1.3143 + // __ jcc(Assembler::notEqual, profile_done); 1.3144 + // __ bne(obj, R0, profile_done); 1.3145 + //__ delayed()->nop(); 1.3146 + 1.3147 + // Object is null; update methodDataOop 1.3148 + //ciMethodData* md = method->method_data(); 1.3149 + //if (md == NULL) { 1.3150 +// bailout("out of memory building methodDataOop"); 1.3151 +// return; 1.3152 + // } 1.3153 + // ciProfileData* data = md->bci_to_data(bci); 1.3154 + //assert(data != NULL, "need data for checkcast"); 1.3155 + // assert(data->is_BitData(), "need BitData for checkcast"); 1.3156 + Register mdo = klass_RInfo; 1.3157 + int oop_index = __ oop_recorder()->find_index(md->constant_encoding()); 1.3158 + RelocationHolder rspec = oop_Relocation::spec(oop_index); 1.3159 + __ relocate(rspec); 1.3160 +#ifndef _LP64 1.3161 + //by_css 1.3162 + __ lui(mdo, Assembler::split_high((int)md->constant_encoding())); 1.3163 + __ addiu(mdo, mdo, Assembler::split_low((int)md->consant_encoding())); 1.3164 +#else 1.3165 + __ li48(mdo, (long)md->constant_encoding()); 1.3166 +#endif 1.3167 + 1.3168 + Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset())); 1.3169 + //FIXME, it very ineffictive to replace orl with 3 mips instruction @jerome, 12/27,06 1.3170 + //__ orl(data_addr, BitData::null_flag_constant()); 1.3171 + int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant()); 1.3172 + __ lw(AT, data_addr); 1.3173 + __ ori(AT, AT, header_bits); 1.3174 + __ sw(AT,data_addr); 1.3175 + __ b(done); 1.3176 + __ delayed()->nop(); 1.3177 + __ bind(not_null); 1.3178 + } else { 1.3179 + __ beq(value, R0, done); 1.3180 + __ delayed()->nop(); 1.3181 + } 1.3182 + //__ verify_oop(obj); 1.3183 + add_debug_info_for_null_check_here(op->info_for_exception()); 1.3184 + __ load_klass(k_RInfo, array); 1.3185 + __ load_klass(klass_RInfo, value); 1.3186 + // get instance klass (it's already uncompressed) 1.3187 + //__ movptr(k_RInfo, Address(k_RInfo, ObjArrayKlass::element_klass_offset())); 1.3188 + __ daddi (k_RInfo, k_RInfo, in_bytes(ObjArrayKlass::element_klass_offset())); 1.3189 + // perform the fast part of the checking logic 1.3190 + //__ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); 1.3191 + // call out-of-line instance of __ check_klass_subtype_slow_path(...): 1.3192 +//1899 __ push(klass_RInfo); 1.3193 +//1900 __ push(k_RInfo); 1.3194 +//1901 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); 1.3195 +//1902 __ pop(klass_RInfo); 1.3196 +//1903 __ pop(k_RInfo); 1.3197 +//1904 // result is a boolean 1.3198 +///1905 __ cmpl(k_RInfo, 0); 1.3199 +//1906 __ jcc(Assembler::equal, *failure_target); 1.3200 +//1907 // fall through to the success case 1.3201 +//1908 1.3202 +//1909 if (op->should_profile()) { 1.3203 +//1910 Register mdo = klass_RInfo, recv = k_RInfo; 1.3204 +//1911 __ bind(profile_cast_success); 1.3205 +//1912 __ mov_metadata(mdo, md->constant_encoding()); 1.3206 +//1913 __ load_klass(recv, value); 1.3207 +//1914 Label update_done; 1.3208 +//1915 type_profile_helper(mdo, md, data, recv, &done); 1.3209 +//1916 __ jmpb(done); 1.3210 +//1917 1.3211 +//1918 __ bind(profile_cast_failure); 1.3212 +//1919 __ mov_metadata(mdo, md->constant_encoding()); 1.3213 +//1920 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); 1.3214 +//1921 __ subptr(counter_addr, DataLayout::counter_increment); 1.3215 +//1922 __ jmp(*stub->entry()); 1.3216 +//1923 } 1.3217 +//1925 __ bind(done); 1.3218 +//1926 } else 1.3219 +//1927 if (code == lir_checkcast) { 1.3220 +//1928 Register obj = op->object()->as_register(); 1.3221 +//1929 Register dst = op->result_opr()->as_register(); 1.3222 +//1930 Label success; 1.3223 +//1931 emit_typecheck_helper(op, &success, op->stub()->entry(), &success); 1.3224 +//1932 __ bind(success); 1.3225 +//1933 if (dst != obj) { 1.3226 +//1934 __ mov(dst, obj); 1.3227 +//1935 } 1.3228 +//1936 } else 1.3229 +//1937 if (code == lir_instanceof) { 1.3230 +//1938 Register obj = op->object()->as_register(); 1.3231 +///1939 Register dst = op->result_opr()->as_register(); 1.3232 +//1940 Label success, failure, done; 1.3233 +//1941 emit_typecheck_helper(op, &success, &failure, &failure); 1.3234 +///1942 __ bind(failure); 1.3235 +//1943 __ xorptr(dst, dst); 1.3236 +//1944 __ jmpb(done); 1.3237 +//1945 __ bind(success); 1.3238 +//1946 __ movptr(dst, 1); 1.3239 +//1947 __ bind(done); 1.3240 +//1948 } else { 1.3241 +//1949 ShouldNotReachHere(); 1.3242 +//1950 } 1.3243 +//FIXME:wuhui. 1.3244 + 1.3245 +} 1.3246 + 1.3247 + 1.3248 +void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { 1.3249 + if (op->code() == lir_cas_long) { 1.3250 +#ifdef _LP64 1.3251 + Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo()); 1.3252 + Register newval = (op->new_value()->is_single_cpu() ? op->new_value()->as_register() : op->new_value()->as_register_lo()); 1.3253 + Register cmpval = (op->cmp_value()->is_single_cpu() ? op->cmp_value()->as_register() : op->cmp_value()->as_register_lo()); 1.3254 + assert(newval != NULL, "new val must be register"); 1.3255 + assert(cmpval != newval, "cmp and new values must be in different registers"); 1.3256 + assert(cmpval != addr, "cmp and addr must be in different registers"); 1.3257 + assert(newval != addr, "new value and addr must be in different registers"); 1.3258 + if (os::is_MP()) {} 1.3259 + __ cmpxchg(newval, addr, cmpval); // 64-bit test-and-set 1.3260 +#else 1.3261 + Register addr = op->addr()->as_register(); 1.3262 + if (os::is_MP()) {} 1.3263 + __ cmpxchg8(op->new_value()->as_register_lo(), 1.3264 + op->new_value()->as_register_hi(), 1.3265 + addr, 1.3266 + op->cmp_value()->as_register_lo(), 1.3267 + op->cmp_value()->as_register_hi()) 1.3268 +#endif 1.3269 + } else if (op->code() == lir_cas_int || op->code() == lir_cas_obj) { 1.3270 + NOT_LP64(assert(op->addr()->is_single_cpu(), "must be single");) 1.3271 + Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo()); 1.3272 + Register newval = op->new_value()->as_register(); 1.3273 + Register cmpval = op->cmp_value()->as_register(); 1.3274 + assert(newval != NULL, "new val must be register"); 1.3275 + assert(cmpval != newval, "cmp and new values must be in different registers"); 1.3276 + assert(cmpval != addr, "cmp and addr must be in different registers"); 1.3277 + assert(newval != addr, "new value and addr must be in different registers"); 1.3278 + if (op->code() == lir_cas_obj) { 1.3279 +#ifdef _LP64 1.3280 + if (UseCompressedOops) { 1.3281 + Register tmp_reg = S7; 1.3282 + __ push(cmpval); 1.3283 + __ encode_heap_oop(cmpval); 1.3284 + __ move(tmp_reg, newval); 1.3285 + __ encode_heap_oop(tmp_reg); 1.3286 + if (os::is_MP()) {} 1.3287 + __ cmpxchg32(tmp_reg, addr, cmpval); // 32-bit test-and-set 1.3288 + __ pop(cmpval); 1.3289 + } else 1.3290 + { 1.3291 + if (os::is_MP()) {} 1.3292 + __ cmpxchg(newval, addr, cmpval); // 64-bit test-and-set 1.3293 + } 1.3294 + } else 1.3295 +#endif 1.3296 + { 1.3297 + __ cmpxchg32(newval, addr, cmpval); // 32-bit test-and-set 1.3298 + } 1.3299 + } else { 1.3300 + Unimplemented(); 1.3301 + } 1.3302 +} 1.3303 +#ifndef MIPS64 1.3304 +void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result) { 1.3305 + Unimplemented(); 1.3306 +} 1.3307 +#endif 1.3308 +void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info,bool pop_fpu_stack) { 1.3309 + assert(info == NULL || ((code == lir_rem || code == lir_div || code == lir_sub) && right->is_double_cpu()), "info is only for ldiv/lrem"); 1.3310 + if (left->is_single_cpu()) { 1.3311 + // left may not be equal to dest on mips. 1.3312 + //assert(left == dest, "left and dest must be equal"); 1.3313 + Register lreg = left->as_register(); 1.3314 + 1.3315 + if (right->is_cpu_register()) { 1.3316 + // cpu register - cpu register 1.3317 + Register rreg, res; 1.3318 + if (right->is_single_cpu()) { 1.3319 + rreg = right->as_register(); 1.3320 +#ifdef _LP64 1.3321 + if(dest->is_double_cpu()) 1.3322 + res = dest->as_register_lo(); 1.3323 + else 1.3324 +#endif 1.3325 + res = dest->as_register(); 1.3326 + } else if (right->is_double_cpu()) { 1.3327 + assert(right->is_double_cpu(),"right must be long"); 1.3328 + rreg = right->as_register_lo(); 1.3329 + res = dest->as_register_lo(); 1.3330 + } else { 1.3331 + ShouldNotReachHere(); 1.3332 + } 1.3333 + switch (code) { 1.3334 + case lir_add: 1.3335 +#ifdef _LP64 1.3336 + if (dest->type() == T_INT) 1.3337 + __ addu32(res, lreg, rreg); 1.3338 + else 1.3339 +#endif 1.3340 + __ addu(res, lreg, rreg); 1.3341 + break; 1.3342 + 1.3343 + case lir_mul: 1.3344 +#ifndef _LP64 1.3345 + //by aoqi 1.3346 + __ mult(lreg, rreg); 1.3347 +#else 1.3348 + __ dmult(lreg, rreg); 1.3349 +#endif 1.3350 + __ nop(); 1.3351 + __ nop(); 1.3352 + __ mflo(res); 1.3353 +#ifdef _LP64 1.3354 + /* Jin: if res < 0, it must be sign-extended. Otherwise it will be a 64-bit positive number. 1.3355 + * 1.3356 + * Example: java.net.URLClassLoader::string2int() 1.3357 + * a6: 0xcafebab 1.3358 + * s0: 16 1.3359 + * 1.3360 + * 104 mul [a6|I] [s0|I] [t0|I] 1.3361 + 0x00000055655e3728: dmult a6, s0 1.3362 + 0x00000055655e372c: sll zero, zero, 0 1.3363 + 0x00000055655e3730: sll zero, zero, 0 1.3364 + 0x00000055655e3734: mflo t0 <-- error 1.3365 + * 1.3366 + * t0: 0xFFFFFFFFcafebab0 (Right) 1.3367 + * t0: 0x00000000cafebab0 (Wrong) 1.3368 + */ 1.3369 + if (dest->type() == T_INT) 1.3370 + __ sll(res, res, 0); 1.3371 +#endif 1.3372 + break; 1.3373 + 1.3374 + case lir_sub: 1.3375 +#ifdef _LP64 1.3376 + if (dest->type() == T_INT) 1.3377 + __ subu32(res, lreg, rreg); 1.3378 + else 1.3379 +#endif 1.3380 + __ subu(res, lreg, rreg); 1.3381 + break; 1.3382 + 1.3383 + default: 1.3384 + ShouldNotReachHere(); 1.3385 + } 1.3386 + } else if (right->is_stack()) { 1.3387 + // cpu register - stack 1.3388 + Unimplemented(); 1.3389 + } else if (right->is_constant()) { 1.3390 + // cpu register - constant 1.3391 + Register res = dest->as_register(); 1.3392 + jint c = right->as_constant_ptr()->as_jint(); 1.3393 + 1.3394 + switch (code) { 1.3395 + case lir_mul_strictfp: 1.3396 + case lir_mul: 1.3397 + __ move(AT, c); 1.3398 +#ifndef _LP64 1.3399 + //by aoqi 1.3400 + __ mult(lreg, AT); 1.3401 +#else 1.3402 + __ dmult(lreg, AT); 1.3403 +#endif 1.3404 + __ nop(); 1.3405 + __ nop(); 1.3406 + __ mflo(res); 1.3407 +#ifdef _LP64 1.3408 + /* Jin: if res < 0, it must be sign-extended. Otherwise it will be a 64-bit positive number. 1.3409 + * 1.3410 + * Example: java.net.URLClassLoader::string2int() 1.3411 + * a6: 0xcafebab 1.3412 + * s0: 16 1.3413 + * 1.3414 + * 104 mul [a6|I] [s0|I] [t0|I] 1.3415 + 0x00000055655e3728: dmult a6, s0 1.3416 + 0x00000055655e372c: sll zero, zero, 0 1.3417 + 0x00000055655e3730: sll zero, zero, 0 1.3418 + 0x00000055655e3734: mflo t0 <-- error 1.3419 + * 1.3420 + * t0: 0xFFFFFFFFcafebab0 (Right) 1.3421 + * t0: 0x00000000cafebab0 (Wrong) 1.3422 + */ 1.3423 + if (dest->type() == T_INT) 1.3424 + __ sll(res, res, 0); 1.3425 +#endif 1.3426 + break; 1.3427 + 1.3428 + case lir_add: 1.3429 + if (Assembler::is_simm16(c)) { 1.3430 + __ addiu(res, lreg, c); 1.3431 + } else { 1.3432 + __ move(AT, c); 1.3433 + __ addu(res, lreg, AT); 1.3434 + } 1.3435 + break; 1.3436 + 1.3437 + case lir_sub: 1.3438 + if (Assembler::is_simm16(-c)) { 1.3439 + __ addi(res, lreg, -c); 1.3440 + } else { 1.3441 + __ move(AT, c); 1.3442 + __ subu(res, lreg, AT); 1.3443 + } 1.3444 + break; 1.3445 + 1.3446 + default: 1.3447 + ShouldNotReachHere(); 1.3448 + } 1.3449 + } else { 1.3450 + ShouldNotReachHere(); 1.3451 + } 1.3452 + 1.3453 + } else if (left->is_double_cpu()) { 1.3454 + Register op1_lo = left->as_register_lo(); 1.3455 + Register op1_hi = left->as_register_hi(); 1.3456 + Register op2_lo; 1.3457 + Register op2_hi; 1.3458 + Register dst_lo; 1.3459 + Register dst_hi; 1.3460 + 1.3461 + if(dest->is_single_cpu()) 1.3462 + { 1.3463 + dst_lo = dest->as_register(); 1.3464 + } 1.3465 + else 1.3466 + { 1.3467 +#ifdef _LP64 1.3468 + dst_lo = dest->as_register_lo(); 1.3469 +#else 1.3470 + dst_lo = dest->as_register_lo(); 1.3471 + dst_hi = dest->as_register_hi(); 1.3472 +#endif 1.3473 + } 1.3474 + if (right->is_constant()) { 1.3475 + op2_lo = AT; 1.3476 + op2_hi = R0; 1.3477 +#ifndef _LP64 1.3478 + __ li(AT, right->as_constant_ptr()->as_jint()); 1.3479 +#else 1.3480 + __ li(AT, right->as_constant_ptr()->as_jlong_bits()); 1.3481 +#endif 1.3482 + } else if (right->is_double_cpu()) { // Double cpu 1.3483 + assert(right->is_double_cpu(),"right must be long"); 1.3484 + assert(dest->is_double_cpu(), "dest must be long"); 1.3485 + op2_lo = right->as_register_lo(); 1.3486 + op2_hi = right->as_register_hi(); 1.3487 + } else { 1.3488 +#ifdef _LP64 1.3489 + op2_lo = right->as_register(); 1.3490 +#else 1.3491 + ShouldNotReachHere(); 1.3492 +#endif 1.3493 + } 1.3494 + 1.3495 + NOT_LP64(assert_different_registers(op1_lo, op1_hi, op2_lo, op2_hi)); 1.3496 +// Jin: Why? 1.3497 +// LP64_ONLY(assert_different_registers(op1_lo, op2_lo)); 1.3498 + 1.3499 + switch (code) { 1.3500 + case lir_add: 1.3501 +#ifndef _LP64 1.3502 + //by aoqi 1.3503 + __ addu(dst_lo, op1_lo, op2_lo); 1.3504 + __ sltu(AT, dst_lo, op2_lo); 1.3505 + __ addu(dst_hi, op1_hi, op2_hi); 1.3506 + __ addu(dst_hi, dst_hi, AT); 1.3507 +#else 1.3508 + __ addu(dst_lo, op1_lo, op2_lo); 1.3509 +#endif 1.3510 + break; 1.3511 + 1.3512 + case lir_sub: 1.3513 +#ifndef _LP64 1.3514 + //by aoqi 1.3515 + __ subu(dst_lo, op1_lo, op2_lo); 1.3516 + __ sltu(AT, op1_lo, dst_lo); 1.3517 + __ subu(dst_hi, op1_hi, op2_hi); 1.3518 + __ subu(dst_hi, dst_hi, AT); 1.3519 +#else 1.3520 + __ subu(dst_lo, op1_lo, op2_lo); 1.3521 +#endif 1.3522 + break; 1.3523 + 1.3524 + case lir_mul: 1.3525 + { 1.3526 + 1.3527 +#ifndef _LP64 1.3528 + //by aoqi 1.3529 + Label zero, quick, done; 1.3530 + //zero? 1.3531 + __ orr(AT, op2_lo, op1_lo); 1.3532 + __ beq(AT, R0, zero); 1.3533 + __ delayed(); 1.3534 + __ move(dst_hi, R0); 1.3535 + 1.3536 + //quick? 1.3537 + __ orr(AT, op2_hi, op1_hi); 1.3538 + __ beq(AT, R0, quick); 1.3539 + __ delayed()->nop(); 1.3540 + 1.3541 + __ multu(op2_lo, op1_hi); 1.3542 + __ nop(); 1.3543 + __ nop(); 1.3544 + __ mflo(dst_hi); 1.3545 + __ multu(op2_hi, op1_lo); 1.3546 + __ nop(); 1.3547 + __ nop(); 1.3548 + __ mflo(AT); 1.3549 + 1.3550 + __ bind(quick); 1.3551 + __ multu(op2_lo, op1_lo); 1.3552 + __ addu(dst_hi, dst_hi, AT); 1.3553 + __ nop(); 1.3554 + __ mflo(dst_lo); 1.3555 + __ mfhi(AT); 1.3556 + __ b(done); 1.3557 + __ delayed()->addu(dst_hi, dst_hi, AT); 1.3558 + 1.3559 + __ bind(zero); 1.3560 + __ move(dst_lo, R0); 1.3561 + __ bind(done); 1.3562 +#else 1.3563 + Label zero, done; 1.3564 + //zero? 1.3565 + __ orr(AT, op2_lo, op1_lo); 1.3566 + __ beq(AT, R0, zero); 1.3567 + __ delayed(); 1.3568 + __ move(dst_hi, R0); 1.3569 + 1.3570 +#ifdef ASSERT 1.3571 + //op1_hi, op2_hi should be 0 1.3572 + { 1.3573 + Label L; 1.3574 + __ beq(op1_hi, R0, L); 1.3575 + __ delayed()->nop(); 1.3576 + __ stop("wrong register, lir_mul"); 1.3577 + __ bind(L); 1.3578 + } 1.3579 + { 1.3580 + Label L; 1.3581 + __ beq(op2_hi, R0, L); 1.3582 + __ delayed()->nop(); 1.3583 + __ stop("wrong register, lir_mul"); 1.3584 + __ bind(L); 1.3585 + } 1.3586 +#endif 1.3587 + 1.3588 + __ multu(op2_lo, op1_lo); 1.3589 + __ nop(); 1.3590 + __ nop(); 1.3591 + __ mflo(dst_lo); 1.3592 + __ b(done); 1.3593 + __ delayed()->nop(); 1.3594 + 1.3595 + __ bind(zero); 1.3596 + __ move(dst_lo, R0); 1.3597 + __ bind(done); 1.3598 +#endif //_LP64 1.3599 + } 1.3600 + break; 1.3601 + 1.3602 + default: 1.3603 + ShouldNotReachHere(); 1.3604 + } 1.3605 + 1.3606 + 1.3607 + } else if (left->is_single_fpu()) { 1.3608 + assert(right->is_single_fpu(),"right must be float"); 1.3609 + assert(dest->is_single_fpu(), "dest must be float"); 1.3610 + 1.3611 + FloatRegister lreg = left->as_float_reg(); 1.3612 + FloatRegister rreg = right->as_float_reg(); 1.3613 + FloatRegister res = dest->as_float_reg(); 1.3614 + 1.3615 + switch (code) { 1.3616 + case lir_add: 1.3617 + __ add_s(res, lreg, rreg); 1.3618 + break; 1.3619 + case lir_sub: 1.3620 + __ sub_s(res, lreg, rreg); 1.3621 + break; 1.3622 + case lir_mul: 1.3623 + case lir_mul_strictfp: 1.3624 + // i dont think we need special handling of this. FIXME 1.3625 + __ mul_s(res, lreg, rreg); 1.3626 + break; 1.3627 + case lir_div: 1.3628 + case lir_div_strictfp: 1.3629 + __ div_s(res, lreg, rreg); 1.3630 + break; 1.3631 + default : ShouldNotReachHere(); 1.3632 + } 1.3633 + } else if (left->is_double_fpu()) { 1.3634 + assert(right->is_double_fpu(),"right must be double"); 1.3635 + assert(dest->is_double_fpu(), "dest must be double"); 1.3636 + 1.3637 + FloatRegister lreg = left->as_double_reg(); 1.3638 + FloatRegister rreg = right->as_double_reg(); 1.3639 + FloatRegister res = dest->as_double_reg(); 1.3640 + 1.3641 + switch (code) { 1.3642 + case lir_add: 1.3643 + __ add_d(res, lreg, rreg); 1.3644 + break; 1.3645 + case lir_sub: 1.3646 + __ sub_d(res, lreg, rreg); 1.3647 + break; 1.3648 + case lir_mul: 1.3649 + case lir_mul_strictfp: 1.3650 + // i dont think we need special handling of this. FIXME 1.3651 + // by yjl 9/13/2005 1.3652 + __ mul_d(res, lreg, rreg); 1.3653 + break; 1.3654 + case lir_div: 1.3655 + case lir_div_strictfp: 1.3656 + __ div_d(res, lreg, rreg); 1.3657 + break; 1.3658 + // case lir_rem: 1.3659 + // __ rem_d(res, lreg, rreg); 1.3660 + // break; 1.3661 + default : ShouldNotReachHere(); 1.3662 + } 1.3663 + } 1.3664 + else if (left->is_single_stack() || left->is_address()) { 1.3665 + assert(left == dest, "left and dest must be equal"); 1.3666 + 1.3667 + Address laddr; 1.3668 + if (left->is_single_stack()) { 1.3669 + laddr = frame_map()->address_for_slot(left->single_stack_ix()); 1.3670 + } else if (left->is_address()) { 1.3671 + laddr = as_Address(left->as_address_ptr()); 1.3672 + } else { 1.3673 + ShouldNotReachHere(); 1.3674 + } 1.3675 + 1.3676 + if (right->is_single_cpu()) { 1.3677 + Register rreg = right->as_register(); 1.3678 + switch (code) { 1.3679 + case lir_add: 1.3680 +#ifndef _LP64 1.3681 + //by aoqi 1.3682 + __ lw(AT, laddr); 1.3683 + __ add(AT, AT, rreg); 1.3684 + __ sw(AT, laddr); 1.3685 +#else 1.3686 + __ ld(AT, laddr); 1.3687 + __ dadd(AT, AT, rreg); 1.3688 + __ sd(AT, laddr); 1.3689 +#endif 1.3690 + break; 1.3691 + case lir_sub: 1.3692 +#ifndef _LP64 1.3693 + //by aoqi 1.3694 + __ lw(AT, laddr); 1.3695 + __ sub(AT,AT,rreg); 1.3696 + __ sw(AT, laddr); 1.3697 +#else 1.3698 + __ ld(AT, laddr); 1.3699 + __ dsub(AT,AT,rreg); 1.3700 + __ sd(AT, laddr); 1.3701 +#endif 1.3702 + break; 1.3703 + default: ShouldNotReachHere(); 1.3704 + } 1.3705 + } else if (right->is_constant()) { 1.3706 +#ifndef _LP64 1.3707 + jint c = right->as_constant_ptr()->as_jint(); 1.3708 +#else 1.3709 + jlong c = right->as_constant_ptr()->as_jlong_bits(); 1.3710 +#endif 1.3711 + switch (code) { 1.3712 + case lir_add: { 1.3713 + __ ld_ptr(AT, laddr); 1.3714 +#ifndef _LP64 1.3715 + __ addi(AT, AT, c); 1.3716 +#else 1.3717 + __ li(T8, c); 1.3718 + __ add(AT, AT, T8); 1.3719 +#endif 1.3720 + __ st_ptr(AT, laddr); 1.3721 + break; 1.3722 + } 1.3723 + case lir_sub: { 1.3724 + __ ld_ptr(AT, laddr); 1.3725 +#ifndef _LP64 1.3726 + __ addi(AT, AT, -c); 1.3727 +#else 1.3728 + __ li(T8, -c); 1.3729 + __ add(AT, AT, T8); 1.3730 +#endif 1.3731 + __ st_ptr(AT, laddr); 1.3732 + break; 1.3733 + } 1.3734 + default: ShouldNotReachHere(); 1.3735 + } 1.3736 + } else { 1.3737 + ShouldNotReachHere(); 1.3738 + } 1.3739 + } else { 1.3740 + ShouldNotReachHere(); 1.3741 + } 1.3742 +} 1.3743 + 1.3744 +void LIR_Assembler::intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr unused, LIR_Opr dest, LIR_Op *op) { 1.3745 +//FIXME,lir_log, lir_log10,lir_abs,lir_sqrt,so many new lir instruction @jerome 1.3746 +if (value->is_double_fpu()) { 1.3747 + // assert(value->fpu_regnrLo() == 0 && dest->fpu_regnrLo() == 0, "both must be on TOS"); 1.3748 + switch(code) { 1.3749 + case lir_log : //__ flog() ; break; 1.3750 + case lir_log10 : //__ flog10() ; 1.3751 + Unimplemented(); 1.3752 + break; 1.3753 + case lir_abs : __ abs_d(dest->as_double_reg(), value->as_double_reg()) ; break; 1.3754 + case lir_sqrt : __ sqrt_d(dest->as_double_reg(), value->as_double_reg()); break; 1.3755 + case lir_sin : 1.3756 + // Should consider not saving ebx if not necessary 1.3757 + __ trigfunc('s', 0); 1.3758 + break; 1.3759 + case lir_cos : 1.3760 + // Should consider not saving ebx if not necessary 1.3761 + // assert(op->as_Op2()->fpu_stack_size() <= 6, "sin and cos need two free stack slots"); 1.3762 + __ trigfunc('c', 0); 1.3763 + break; 1.3764 + case lir_tan : 1.3765 + // Should consider not saving ebx if not necessary 1.3766 + __ trigfunc('t', 0); 1.3767 + break; 1.3768 + default : ShouldNotReachHere(); 1.3769 + } 1.3770 + } else { 1.3771 + Unimplemented(); 1.3772 + } 1.3773 +} 1.3774 + 1.3775 +//FIXME, if right is on the stack! 1.3776 +void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst) { 1.3777 + if (left->is_single_cpu()) { 1.3778 + Register dstreg = dst->as_register(); 1.3779 + Register reg = left->as_register(); 1.3780 + if (right->is_constant()) { 1.3781 + int val = right->as_constant_ptr()->as_jint(); 1.3782 + __ move(AT, val); 1.3783 + switch (code) { 1.3784 + case lir_logic_and: 1.3785 + __ andr (dstreg, reg, AT); 1.3786 + break; 1.3787 + case lir_logic_or: 1.3788 + __ orr(dstreg, reg, AT); 1.3789 + break; 1.3790 + case lir_logic_xor: 1.3791 + __ xorr(dstreg, reg, AT); 1.3792 + break; 1.3793 + default: ShouldNotReachHere(); 1.3794 + } 1.3795 + } else if (right->is_stack()) { 1.3796 + // added support for stack operands 1.3797 + Address raddr = frame_map()->address_for_slot(right->single_stack_ix()); 1.3798 + switch (code) { 1.3799 + case lir_logic_and: 1.3800 + //FIXME. lw or ld_ptr? 1.3801 + __ lw(AT, raddr); 1.3802 + __ andr(reg, reg,AT); 1.3803 + break; 1.3804 + case lir_logic_or: 1.3805 + __ lw(AT, raddr); 1.3806 + __ orr(reg, reg, AT); 1.3807 + break; 1.3808 + case lir_logic_xor: 1.3809 + __ lw(AT, raddr); 1.3810 + __ xorr(reg, reg, AT); 1.3811 + break; 1.3812 + default: ShouldNotReachHere(); 1.3813 + } 1.3814 + } else { 1.3815 + Register rright = right->as_register(); 1.3816 + switch (code) { 1.3817 + case lir_logic_and: __ andr (dstreg, reg, rright); break; 1.3818 + case lir_logic_or : __ orr (dstreg, reg, rright); break; 1.3819 + case lir_logic_xor: __ xorr (dstreg, reg, rright); break; 1.3820 + default: ShouldNotReachHere(); 1.3821 + } 1.3822 + } 1.3823 + } else { 1.3824 + Register l_lo = left->as_register_lo(); 1.3825 + Register dst_lo = dst->as_register_lo(); 1.3826 +#ifndef _LP64 1.3827 + Register l_hi = left->as_register_hi(); 1.3828 + Register dst_hi = dst->as_register_hi(); 1.3829 +#endif 1.3830 + 1.3831 + if (right->is_constant()) { 1.3832 +#ifndef _LP64 1.3833 + 1.3834 + int r_lo = right->as_constant_ptr()->as_jint_lo(); 1.3835 + int r_hi = right->as_constant_ptr()->as_jint_hi(); 1.3836 + 1.3837 + switch (code) { 1.3838 + case lir_logic_and: 1.3839 + __ move(AT, r_lo); 1.3840 + __ andr(dst_lo, l_lo, AT); 1.3841 + __ move(AT, r_hi); 1.3842 + __ andr(dst_hi, l_hi, AT); 1.3843 + break; 1.3844 + 1.3845 + case lir_logic_or: 1.3846 + __ move(AT, r_lo); 1.3847 + __ orr(dst_lo, l_lo, AT); 1.3848 + __ move(AT, r_hi); 1.3849 + __ orr(dst_hi, l_hi, AT); 1.3850 + break; 1.3851 + 1.3852 + case lir_logic_xor: 1.3853 + __ move(AT, r_lo); 1.3854 + __ xorr(dst_lo, l_lo, AT); 1.3855 + __ move(AT, r_hi); 1.3856 + __ xorr(dst_hi, l_hi, AT); 1.3857 + break; 1.3858 + 1.3859 + default: ShouldNotReachHere(); 1.3860 + } 1.3861 +#else 1.3862 + __ li(AT, right->as_constant_ptr()->as_jlong()); 1.3863 + 1.3864 + switch (code) { 1.3865 + case lir_logic_and: 1.3866 + __ andr(dst_lo, l_lo, AT); 1.3867 + break; 1.3868 + 1.3869 + case lir_logic_or: 1.3870 + __ orr(dst_lo, l_lo, AT); 1.3871 + break; 1.3872 + 1.3873 + case lir_logic_xor: 1.3874 + __ xorr(dst_lo, l_lo, AT); 1.3875 + break; 1.3876 + 1.3877 + default: ShouldNotReachHere(); 1.3878 + } 1.3879 +#endif 1.3880 + 1.3881 + } else { 1.3882 + Register r_lo = right->as_register_lo(); 1.3883 + Register r_hi = right->as_register_hi(); 1.3884 + 1.3885 + switch (code) { 1.3886 + case lir_logic_and: 1.3887 + __ andr(dst_lo, l_lo, r_lo); 1.3888 + NOT_LP64(__ andr(dst_hi, l_hi, r_hi);) 1.3889 + break; 1.3890 + case lir_logic_or: 1.3891 + __ orr(dst_lo, l_lo, r_lo); 1.3892 + NOT_LP64(__ orr(dst_hi, l_hi, r_hi);) 1.3893 + break; 1.3894 + case lir_logic_xor: 1.3895 + __ xorr(dst_lo, l_lo, r_lo); 1.3896 + NOT_LP64(__ xorr(dst_hi, l_hi, r_hi);) 1.3897 + break; 1.3898 + default: ShouldNotReachHere(); 1.3899 + } 1.3900 + } 1.3901 + } 1.3902 +} 1.3903 + 1.3904 +//done here. aoqi. 12-12 22:25 1.3905 +// we assume that eax and edx can be overwritten 1.3906 +void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info) { 1.3907 + 1.3908 + assert(left->is_single_cpu(), "left must be register"); 1.3909 + assert(right->is_single_cpu() || right->is_constant(), "right must be register or constant"); 1.3910 + assert(result->is_single_cpu(), "result must be register"); 1.3911 + 1.3912 + Register lreg = left->as_register(); 1.3913 + Register dreg = result->as_register(); 1.3914 + 1.3915 + if (right->is_constant()) { 1.3916 + int divisor = right->as_constant_ptr()->as_jint(); 1.3917 + assert(divisor!=0, "must be nonzero"); 1.3918 +#ifndef _LP64 1.3919 + __ move(AT, divisor); 1.3920 + __ div(lreg, AT); 1.3921 +#else 1.3922 + __ li(AT, divisor); 1.3923 + __ ddiv(lreg, AT); 1.3924 +#endif 1.3925 + int idivl_offset = code_offset(); 1.3926 + 1.3927 + /* 2012/4/21 Jin: In MIPS, div does not cause exception. 1.3928 + We must trap an exception manually. */ 1.3929 + __ teq(R0, AT, 0x7); 1.3930 + __ nop(); 1.3931 + __ nop(); 1.3932 + add_debug_info_for_div0(idivl_offset, info); 1.3933 + } else { 1.3934 + Register rreg = right->as_register(); 1.3935 +#ifndef _LP64 1.3936 + __ div(lreg, rreg); 1.3937 +#else 1.3938 + __ ddiv(lreg, rreg); 1.3939 +#endif 1.3940 + 1.3941 + int idivl_offset = code_offset(); 1.3942 + __ teq(R0, rreg, 0x7); 1.3943 + __ nop(); 1.3944 + __ nop(); 1.3945 + add_debug_info_for_div0(idivl_offset, info); 1.3946 + } 1.3947 + 1.3948 + // get the result 1.3949 + if (code == lir_irem) { 1.3950 + __ mfhi(dreg); 1.3951 +#ifdef _LP64 1.3952 + if (result->type() == T_INT) 1.3953 + __ sll(dreg, dreg, 0); 1.3954 +#endif 1.3955 + } else if (code == lir_idiv) { 1.3956 + __ mflo(dreg); 1.3957 + } else { 1.3958 + ShouldNotReachHere(); 1.3959 + } 1.3960 +} 1.3961 + 1.3962 +void LIR_Assembler::arithmetic_frem(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info) { 1.3963 + if (left->is_single_fpu()) { 1.3964 + assert(right->is_single_fpu(),"right must be float"); 1.3965 + assert(result->is_single_fpu(), "dest must be float"); 1.3966 + assert(temp->is_single_fpu(), "dest must be float"); 1.3967 + 1.3968 + FloatRegister lreg = left->as_float_reg(); 1.3969 + FloatRegister rreg = right->as_float_reg(); 1.3970 + FloatRegister res = result->as_float_reg(); 1.3971 + FloatRegister tmp = temp->as_float_reg(); 1.3972 + 1.3973 + switch (code) { 1.3974 + case lir_frem: 1.3975 + __ rem_s(res, lreg, rreg, tmp); 1.3976 + break; 1.3977 + default : ShouldNotReachHere(); 1.3978 + } 1.3979 + } else if (left->is_double_fpu()) { 1.3980 + assert(right->is_double_fpu(),"right must be double"); 1.3981 + assert(result->is_double_fpu(), "dest must be double"); 1.3982 + assert(temp->is_double_fpu(), "dest must be double"); 1.3983 + 1.3984 + FloatRegister lreg = left->as_double_reg(); 1.3985 + FloatRegister rreg = right->as_double_reg(); 1.3986 + FloatRegister res = result->as_double_reg(); 1.3987 + FloatRegister tmp = temp->as_double_reg(); 1.3988 + 1.3989 + switch (code) { 1.3990 + case lir_frem: 1.3991 + __ rem_d(res, lreg, rreg, tmp); 1.3992 + break; 1.3993 + default : ShouldNotReachHere(); 1.3994 + } 1.3995 + } 1.3996 +} 1.3997 + 1.3998 +void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst,LIR_Op2 * op) { 1.3999 + Register dstreg = dst->as_register(); 1.4000 + if (code == lir_cmp_fd2i) { 1.4001 + if (left->is_single_fpu()) { 1.4002 + FloatRegister leftreg = left->as_float_reg(); 1.4003 + FloatRegister rightreg = right->as_float_reg(); 1.4004 + 1.4005 + Label done; 1.4006 + // equal? 1.4007 + __ c_eq_s(leftreg, rightreg); 1.4008 + __ bc1t(done); 1.4009 + __ delayed(); 1.4010 + __ move(dstreg, R0); 1.4011 + // less? 1.4012 + __ c_olt_s(leftreg, rightreg); 1.4013 + __ bc1t(done); 1.4014 + __ delayed(); 1.4015 + __ move(dstreg, -1); 1.4016 + // great 1.4017 + __ move(dstreg, 1); 1.4018 + 1.4019 + __ bind(done); 1.4020 + } else { 1.4021 + assert(left->is_double_fpu(), "Must double"); 1.4022 + FloatRegister leftreg = left->as_double_reg(); 1.4023 + FloatRegister rightreg = right->as_double_reg(); 1.4024 + 1.4025 + Label done; 1.4026 + // equal? 1.4027 + __ c_eq_d(leftreg, rightreg); 1.4028 + __ bc1t(done); 1.4029 + __ delayed(); 1.4030 + __ move(dstreg, R0); 1.4031 + // less? 1.4032 + __ c_olt_d(leftreg, rightreg); 1.4033 + __ bc1t(done); 1.4034 + __ delayed(); 1.4035 + __ move(dstreg, -1); 1.4036 + // great 1.4037 + __ move(dstreg, 1); 1.4038 + 1.4039 + __ bind(done); 1.4040 + } 1.4041 + } else if (code == lir_ucmp_fd2i) { 1.4042 + if (left->is_single_fpu()) { 1.4043 + FloatRegister leftreg = left->as_float_reg(); 1.4044 + FloatRegister rightreg = right->as_float_reg(); 1.4045 + 1.4046 + Label done; 1.4047 + // equal? 1.4048 + __ c_eq_s(leftreg, rightreg); 1.4049 + __ bc1t(done); 1.4050 + __ delayed(); 1.4051 + __ move(dstreg, R0); 1.4052 + // less? 1.4053 + __ c_ult_s(leftreg, rightreg); 1.4054 + __ bc1t(done); 1.4055 + __ delayed(); 1.4056 + __ move(dstreg, -1); 1.4057 + // great 1.4058 + __ move(dstreg, 1); 1.4059 + 1.4060 + __ bind(done); 1.4061 + } else { 1.4062 + assert(left->is_double_fpu(), "Must double"); 1.4063 + FloatRegister leftreg = left->as_double_reg(); 1.4064 + FloatRegister rightreg = right->as_double_reg(); 1.4065 + 1.4066 + Label done; 1.4067 + // equal? 1.4068 + __ c_eq_d(leftreg, rightreg); 1.4069 + __ bc1t(done); 1.4070 + __ delayed(); 1.4071 + __ move(dstreg, R0); 1.4072 + // less? 1.4073 + __ c_ult_d(leftreg, rightreg); 1.4074 + __ bc1t(done); 1.4075 + __ delayed(); 1.4076 + __ move(dstreg, -1); 1.4077 + // great 1.4078 + __ move(dstreg, 1); 1.4079 + 1.4080 + __ bind(done); 1.4081 + } 1.4082 + } else { 1.4083 + assert(code == lir_cmp_l2i, "check"); 1.4084 + Register l_lo, l_hi, r_lo, r_hi, d_lo, d_hi; 1.4085 + l_lo = left->as_register_lo(); 1.4086 + l_hi = left->as_register_hi(); 1.4087 + r_lo = right->as_register_lo(); 1.4088 + r_hi = right->as_register_hi(); 1.4089 + 1.4090 + Label done; 1.4091 +#ifndef _LP64 1.4092 + // less? 1.4093 + __ slt(AT, l_hi, r_hi); 1.4094 + __ bne(AT, R0, done); 1.4095 + __ delayed(); 1.4096 + __ move(dstreg, -1); 1.4097 + // great? 1.4098 + __ slt(AT, r_hi, l_hi); 1.4099 + __ bne(AT, R0, done); 1.4100 + __ delayed(); 1.4101 + __ move(dstreg, 1); 1.4102 +#endif 1.4103 + 1.4104 + // now compare low 32 bits 1.4105 + // below? 1.4106 +#ifndef _LP64 1.4107 + __ sltu(AT, l_lo, r_lo); 1.4108 +#else 1.4109 + __ slt(AT, l_lo, r_lo); 1.4110 +#endif 1.4111 + __ bne(AT, R0, done); 1.4112 + __ delayed(); 1.4113 + __ move(dstreg, -1); 1.4114 + // above? 1.4115 +#ifndef _LP64 1.4116 + __ sltu(AT, r_lo, l_lo); 1.4117 +#else 1.4118 + __ slt(AT, r_lo, l_lo); 1.4119 +#endif 1.4120 + __ bne(AT, R0, done); 1.4121 + __ delayed(); 1.4122 + __ move(dstreg, 1); 1.4123 + // equal 1.4124 + __ move(dstreg, R0); 1.4125 + 1.4126 + __ bind(done); 1.4127 + } 1.4128 +} 1.4129 + 1.4130 + 1.4131 +void LIR_Assembler::align_call(LIR_Code code) { 1.4132 +//FIXME. aoqi, this right? 1.4133 +// do nothing since all instructions are word aligned on sparc 1.4134 +/* 1.4135 + if (os::is_MP()) { 1.4136 + // make sure that the displacement word of the call ends up word aligned 1.4137 + int offset = __ offset(); 1.4138 + switch (code) { 1.4139 + case lir_static_call: 1.4140 + case lir_optvirtual_call: 1.4141 + offset += NativeCall::displacement_offset; 1.4142 + break; 1.4143 + case lir_icvirtual_call: 1.4144 + offset += NativeCall::displacement_offset + NativeMovConstReg::instruction_size; 1.4145 + break; 1.4146 + case lir_virtual_call: // currently, sparc-specific for niagara 1.4147 + default: ShouldNotReachHere(); 1.4148 + } 1.4149 + while (offset++ % BytesPerWord != 0) { 1.4150 + __ nop(); 1.4151 + } 1.4152 + } 1.4153 +*/ 1.4154 +} 1.4155 + 1.4156 + 1.4157 +void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) { 1.4158 + //assert(!os::is_MP() || (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0, "must be aligned"); 1.4159 + __ call(op->addr(), rtype); 1.4160 + __ delayed()->nop(); 1.4161 + add_call_info(code_offset(), op->info()); 1.4162 +} 1.4163 + 1.4164 + 1.4165 +void LIR_Assembler::ic_call(LIR_OpJavaCall* op) { 1.4166 + RelocationHolder rh = virtual_call_Relocation::spec(pc()); 1.4167 +// int oop_index = __ oop_recorder()->allocate_oop_index((jobject)Universe::non_oop_word()); 1.4168 +// RelocationHolder rspec = oop_Relocation::spec(oop_index); 1.4169 +/// __ relocate(rspec); 1.4170 +#ifndef _LP64 1.4171 +//by_css 1.4172 + __ lui(IC_Klass, Assembler::split_high((int)Universe::non_oop_word())); 1.4173 + __ addiu(IC_Klass, IC_Klass, Assembler::split_low((int)Universe::non_oop_word())); 1.4174 +#else 1.4175 + __ li48(IC_Klass, (long)Universe::non_oop_word()); 1.4176 +#endif 1.4177 + __ call(op->addr(), rh); 1.4178 + __ delayed()->nop(); 1.4179 +// add_call_info(code_offset(), info); 1.4180 + 1.4181 + add_call_info(code_offset(), op->info()); 1.4182 + assert(!os::is_MP() || 1.4183 + (__ offset() - NativeCall::instruction_size + NativeCall::displacement_offset) % BytesPerWord == 0, 1.4184 + "must be aligned"); 1.4185 + 1.4186 +} 1.4187 + 1.4188 + 1.4189 +/* Currently, vtable-dispatch is only enabled for sparc platforms */ 1.4190 +void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) { 1.4191 + ShouldNotReachHere(); 1.4192 +} 1.4193 + 1.4194 + 1.4195 + 1.4196 +void LIR_Assembler::emit_static_call_stub() { 1.4197 + address call_pc = __ pc(); 1.4198 + address stub = __ start_a_stub(call_stub_size); 1.4199 + if (stub == NULL) { 1.4200 + bailout("static call stub overflow"); 1.4201 + return; 1.4202 + } 1.4203 + 1.4204 + int start = __ offset(); 1.4205 + /* 1.4206 + if (os::is_MP()) { 1.4207 + // make sure that the displacement word of the call ends up word aligned 1.4208 + int offset = __ offset() + NativeMovConstReg::instruction_size + NativeCall::displacement_offset; 1.4209 + while (offset++ % BytesPerWord != 0) { 1.4210 + __ nop(); 1.4211 + } 1.4212 + } 1.4213 + */ 1.4214 + __ relocate(static_stub_Relocation::spec(call_pc)); 1.4215 + jobject o=NULL; 1.4216 + int oop_index = __ oop_recorder()->allocate_oop_index((jobject)o); 1.4217 + RelocationHolder rspec = oop_Relocation::spec(oop_index); 1.4218 + __ relocate(rspec); 1.4219 +//see set_to_interpreted 1.4220 +#ifndef _LP64 1.4221 + __ lui(T7, Assembler::split_high((int)o)); 1.4222 + __ addiu(T7, T7, Assembler::split_low((int)o)); 1.4223 +#else 1.4224 + __ li48(Rmethod, (long)o); 1.4225 +#endif 1.4226 +#ifndef _LP64 1.4227 + __ lui(AT, Assembler::split_high((int)-1)); 1.4228 + __ addiu(AT, AT, Assembler::split_low((int)-1)); 1.4229 +#else 1.4230 + __ li48(AT, (long)-1); 1.4231 +#endif 1.4232 + //assert(!os::is_MP() || ((__ offset() + 1) % BytesPerWord) == 0, "must be aligned on MP"); 1.4233 + __ jr(AT); 1.4234 + __ delayed()->nop(); 1.4235 + assert(__ offset() - start <= call_stub_size, "stub too big"); 1.4236 + __ end_a_stub(); 1.4237 +} 1.4238 + 1.4239 + 1.4240 +void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) { 1.4241 + assert(exceptionOop->as_register()== V0, "must match"); 1.4242 + assert(exceptionPC->as_register()== V1, "must match"); 1.4243 + 1.4244 + // exception object is not added to oop map by LinearScan 1.4245 + // (LinearScan assumes that no oops are in fixed registers) 1.4246 + 1.4247 + info->add_register_oop(exceptionOop); 1.4248 + //if (!unwind) { 1.4249 + // get current pc information 1.4250 + // pc is only needed if the method has an exception handler, the unwind code does not need it. 1.4251 +#ifndef _LP64 1.4252 +//by_css 1.4253 + int pc_for_athrow = (int)__ pc(); 1.4254 + int pc_for_athrow_offset = __ offset(); 1.4255 + Register epc = exceptionPC->as_register(); 1.4256 + //__ nop(); 1.4257 + // pc_for_athrow can not point to itself (relocInfo restriction), no need now 1.4258 + __ relocate(relocInfo::internal_pc_type); 1.4259 + __ lui(epc, Assembler::split_high(pc_for_athrow)); 1.4260 + __ addiu(epc, epc, Assembler::split_low(pc_for_athrow)); 1.4261 +#else 1.4262 + long pc_for_athrow = (long)__ pc(); 1.4263 + int pc_for_athrow_offset = __ offset(); 1.4264 + Register epc = exceptionPC->as_register(); 1.4265 + //__ nop(); 1.4266 + // pc_for_athrow can not point to itself (relocInfo restriction), no need now 1.4267 + __ relocate(relocInfo::internal_pc_type); 1.4268 + __ li48(epc, pc_for_athrow); 1.4269 +#endif 1.4270 + add_call_info(pc_for_athrow_offset, info); // for exception handler 1.4271 + __ verify_not_null_oop(V0); 1.4272 + // search an exception handler (eax: exception oop, edx: throwing pc) 1.4273 + if (compilation()->has_fpu_code()) { 1.4274 + __ call(Runtime1::entry_for(Runtime1::handle_exception_id), 1.4275 + relocInfo::runtime_call_type); 1.4276 + } else { 1.4277 + __ call(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id), 1.4278 + relocInfo::runtime_call_type); 1.4279 + } 1.4280 +// } else { 1.4281 +// __ call(Runtime1::entry_for(Runtime1::unwind_exception_id), 1.4282 +// relocInfo::runtime_call_type); 1.4283 +// } 1.4284 + 1.4285 + // enough room for two byte trap 1.4286 + __ delayed()->nop(); 1.4287 +} 1.4288 + 1.4289 +void LIR_Assembler::unwind_op(LIR_Opr exceptionOop){ 1.4290 + assert(exceptionOop->as_register()== FSR, "must match"); 1.4291 + __ b(_unwind_handler_entry); 1.4292 + __ delayed()->nop(); 1.4293 + } 1.4294 + 1.4295 +void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) { 1.4296 + // optimized version for linear scan: 1.4297 + // * tmp must be unused 1.4298 + assert(tmp->is_illegal(), "wasting a register if tmp is allocated"); 1.4299 + 1.4300 +#ifdef _LP64 1.4301 + Register count_reg = count->as_register(); 1.4302 + Register value_reg; 1.4303 + Register dest_reg; 1.4304 + if (left->is_single_cpu()) { 1.4305 + value_reg = left->as_register(); 1.4306 + dest_reg = dest->as_register(); 1.4307 + 1.4308 + } else if (left->is_double_cpu()) { 1.4309 + value_reg = left->as_register_lo(); 1.4310 + dest_reg = dest->as_register_lo(); 1.4311 + } else { 1.4312 + ShouldNotReachHere(); 1.4313 + } 1.4314 + assert_different_registers(count_reg, value_reg); 1.4315 + switch (code) { 1.4316 + case lir_shl: 1.4317 + if (dest->type() == T_INT) 1.4318 + __ sllv(dest_reg, value_reg, count_reg); 1.4319 + else 1.4320 + __ dsllv(dest_reg, value_reg, count_reg); 1.4321 + break; 1.4322 +//__ dsllv(dest_reg, value_reg, count_reg); break; 1.4323 + case lir_shr: __ dsrav(dest_reg, value_reg, count_reg); break; 1.4324 + case lir_ushr: 1.4325 +#if 1 1.4326 +/* 1.4327 + Jin: in java, ushift_right requires 32-bit UNSIGNED operation! 1.4328 + However, dsrl will shift in company with the highest 32 bits. 1.4329 + Thus, if the source register contains a negative value, 1.4330 + the resulti is incorrect. 1.4331 + * DoubleCvt.java 1.4332 + * 1.4333 + * static int inp (int shift) 1.4334 + * { 1.4335 + * return -1 >>> (32 - shift); 1.4336 + * } 1.4337 + * 1.4338 + * 26 ushift_right [t0|I] [a4|I] [a6|I] 1.4339 + * 0x00000055616d2a98: dsrl a6, t0, a4 <-- error 1.4340 + */ 1.4341 + 1.4342 +// java.math.MutableBigInteger::primitiveRightShift 1.4343 +// 1.4344 +// 108 ushift_right [a6|I] [a4|I] [a4|I] 1.4345 +// 0x00000055646d2f70: dsll32 a4, a6, 0 \ 1.4346 +// 0x00000055646d2f74: dsrl32 a4, a4, 0 |- error! 1.4347 +// 0x00000055646d2f78: dsrl a4, a4, a4 / 1.4348 + if (left->type() == T_INT && dest->type() == T_INT) 1.4349 + { 1.4350 + __ dsll32(AT, value_reg, 0); // Omit the high 32 bits 1.4351 + __ dsrl32(AT, AT, 0); 1.4352 + __ dsrlv(dest_reg, AT, count_reg); // Unsigned right shift 1.4353 + break; 1.4354 + } 1.4355 +#endif 1.4356 + __ dsrlv(dest_reg, value_reg, count_reg); break; 1.4357 + default: ShouldNotReachHere(); 1.4358 + } 1.4359 +#else 1.4360 + if (left->is_single_cpu()) { 1.4361 + Register value_reg = left->as_register(); 1.4362 + Register count_reg = count->as_register(); 1.4363 + Register dest_reg = dest->as_register(); 1.4364 + assert_different_registers(count_reg, value_reg); 1.4365 + 1.4366 + switch (code) { 1.4367 + case lir_shl: __ sllv(dest_reg, value_reg, count_reg); break; 1.4368 + case lir_shr: __ srav(dest_reg, value_reg, count_reg); break; 1.4369 + case lir_ushr: __ srlv(dest_reg, value_reg, count_reg); break; 1.4370 + default: ShouldNotReachHere(); 1.4371 + } 1.4372 + 1.4373 + } else if (left->is_double_cpu()) { 1.4374 + Register creg = count->as_register(); 1.4375 + Register lo = left->as_register_lo(); 1.4376 + Register hi = left->as_register_hi(); 1.4377 + Register dlo = dest->as_register_lo(); 1.4378 + Register dhi = dest->as_register_hi(); 1.4379 + 1.4380 + __ andi(creg, creg, 0x3f); 1.4381 + switch (code) { 1.4382 + case lir_shl: 1.4383 + { 1.4384 + Label normal, done, notzero; 1.4385 + 1.4386 + //count=0 1.4387 + __ bne(creg, R0, notzero); 1.4388 + __ delayed()->nop(); 1.4389 + __ move(dlo, lo); 1.4390 + __ b(done); 1.4391 + __ delayed(); 1.4392 + __ move(dhi, hi); 1.4393 + 1.4394 + //count>=32 1.4395 + __ bind(notzero); 1.4396 + __ sltiu(AT, creg, BitsPerWord); 1.4397 + __ bne(AT, R0, normal); 1.4398 + __ delayed(); 1.4399 + __ addiu(AT, creg, (-1) * BitsPerWord); 1.4400 + __ sllv(dhi, lo, AT); 1.4401 + __ b(done); 1.4402 + __ delayed(); 1.4403 + __ move(dlo, R0); 1.4404 + 1.4405 + //count<32 1.4406 + __ bind(normal); 1.4407 + __ sllv(dhi, hi, creg); 1.4408 + __ move(AT, BitsPerWord); 1.4409 + __ sub(AT, AT, creg); 1.4410 + __ srlv(AT, lo, AT); 1.4411 + __ orr(dhi, dhi, AT); 1.4412 + __ sllv(dlo, lo, creg); 1.4413 + __ bind(done); 1.4414 + } 1.4415 + break; 1.4416 + case lir_shr: 1.4417 + { 1.4418 + Label normal, done, notzero; 1.4419 + 1.4420 + //count=0 1.4421 + __ bne(creg, R0, notzero); 1.4422 + __ delayed()->nop(); 1.4423 + __ move(dhi, hi); 1.4424 + __ b(done); 1.4425 + __ delayed(); 1.4426 + __ move(dlo, lo); 1.4427 + 1.4428 + //count>=32 1.4429 + __ bind(notzero); 1.4430 + __ sltiu(AT, creg, BitsPerWord); 1.4431 + __ bne(AT, R0, normal); 1.4432 + __ delayed(); 1.4433 + __ addiu(AT, creg, (-1) * BitsPerWord); 1.4434 + __ srav(dlo, hi, AT); 1.4435 + __ b(done); 1.4436 + __ delayed(); 1.4437 + __ sra(dhi, hi, BitsPerWord - 1); 1.4438 + 1.4439 + //count<32 1.4440 + __ bind(normal); 1.4441 + __ srlv(dlo, lo, creg); 1.4442 + __ move(AT, BitsPerWord); 1.4443 + __ sub(AT, AT, creg); 1.4444 + __ sllv(AT, hi, AT); 1.4445 + __ orr(dlo, dlo, AT); 1.4446 + __ srav(dhi, hi, creg); 1.4447 + __ bind(done); 1.4448 + } 1.4449 + break; 1.4450 + case lir_ushr: 1.4451 + { 1.4452 + Label normal, done, notzero; 1.4453 + 1.4454 + //count=zero 1.4455 + __ bne(creg, R0, notzero); 1.4456 + __ delayed()->nop(); 1.4457 + __ move(dhi, hi); 1.4458 + __ b(done); 1.4459 + __ delayed(); 1.4460 + __ move(dlo, lo); 1.4461 + 1.4462 + //count>=32 1.4463 + __ bind(notzero); 1.4464 + __ sltiu(AT, creg, BitsPerWord); 1.4465 + __ bne(AT, R0, normal); 1.4466 + __ delayed(); 1.4467 + __ addi(AT, creg, (-1) * BitsPerWord); 1.4468 + __ srlv(dlo, hi, AT); 1.4469 + __ b(done); 1.4470 + __ delayed(); 1.4471 + __ move(dhi, R0); 1.4472 + 1.4473 + //count<32 1.4474 + __ bind(normal); 1.4475 + __ srlv(dlo, lo, creg); 1.4476 + __ move(AT, BitsPerWord); 1.4477 + __ sub(AT, AT, creg); 1.4478 + __ sllv(AT, hi, AT); 1.4479 + __ orr(dlo, dlo, AT); 1.4480 + __ srlv(dhi, hi, creg); 1.4481 + __ bind(done); 1.4482 + } 1.4483 + break; 1.4484 + default: ShouldNotReachHere(); 1.4485 + } 1.4486 + } else { 1.4487 + ShouldNotReachHere(); 1.4488 + } 1.4489 +#endif 1.4490 + 1.4491 +} 1.4492 + 1.4493 +void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, jint count, LIR_Opr dest) { 1.4494 + if (dest->is_single_cpu()) { 1.4495 +/* In WebClient, 1.4496 + * virtual jboolean java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl.compareAndSet 1.4497 + * 1.4498 + * 130 ushift_right [a4a4|J] [int:9|I] [a4|L] 1.4499 + */ 1.4500 + Register value_reg = left->is_single_cpu() ? left->as_register() : left->as_register_lo(); 1.4501 + Register dest_reg = dest->as_register(); 1.4502 + count = count & 0x1F; // Java spec 1.4503 + 1.4504 + switch (code) { 1.4505 +#ifdef _LP64 1.4506 + case lir_shl: 1.4507 + if (dest->type() == T_INT) 1.4508 + __ sll(dest_reg, value_reg, count); 1.4509 + else 1.4510 + __ dsll(dest_reg, value_reg, count); 1.4511 + break; 1.4512 + case lir_shr: __ dsra(dest_reg, value_reg, count); break; 1.4513 + case lir_ushr: 1.4514 +#if 1 1.4515 + if (left->type() == T_INT && dest->type() == T_INT) 1.4516 + { 1.4517 + /* Jin: in java, ushift_right requires 32-bit UNSIGNED operation! 1.4518 + However, dsrl will shift in company with the highest 32 bits. 1.4519 + Thus, if the source register contains a negative value, 1.4520 + the resulti is incorrect. 1.4521 + 1.4522 + Example: in java.util.HashMap.get() 1.4523 + 1.4524 + 68 ushift_right [t0|I] [int:20|I] [a4|I] 1.4525 + dsrl a4, t0, 20 1.4526 + 1.4527 + t0: 0xFFFFFFFF87654321 (64bits for 0x87654321) 1.4528 + 1.4529 + ushift_right t0, 16 -> a4 1.4530 + 1.4531 + a4: 00000000 00008765 (right) 1.4532 + a4: FFFFFFFF FFFF8765 (wrong) 1.4533 + */ 1.4534 + __ dsll32(dest_reg, value_reg, 0); // Omit the high 32 bits 1.4535 + __ dsrl32(dest_reg, dest_reg, count); // Unsigned right shift 1.4536 + break; 1.4537 + } 1.4538 +#endif 1.4539 + 1.4540 + __ dsrl(dest_reg, value_reg, count); 1.4541 + break; 1.4542 +#else 1.4543 + case lir_shl: __ sll(dest_reg, value_reg, count); break; 1.4544 + case lir_shr: __ sra(dest_reg, value_reg, count); break; 1.4545 + case lir_ushr: __ srl(dest_reg, value_reg, count); break; 1.4546 +#endif 1.4547 + default: ShouldNotReachHere(); 1.4548 + } 1.4549 + 1.4550 + } else if (dest->is_double_cpu()) { 1.4551 + Register valuelo = left->is_single_cpu() ? left->as_register() : left->as_register_lo(); 1.4552 + Register destlo = dest->as_register_lo(); 1.4553 + count = count & 0x3f; 1.4554 +#ifdef _LP64 1.4555 + switch (code) { 1.4556 + case lir_shl: __ dsll(destlo, valuelo, count); break; 1.4557 + case lir_shr: __ dsra(destlo, valuelo, count); break; 1.4558 + case lir_ushr: __ dsrl(destlo, valuelo, count); break; 1.4559 + default: ShouldNotReachHere(); 1.4560 + } 1.4561 +#else 1.4562 + Register desthi = dest->as_register_hi(); 1.4563 + Register valuehi = left->as_register_hi(); 1.4564 + assert_different_registers(destlo, valuehi, desthi); 1.4565 + switch (code) { 1.4566 + case lir_shl: 1.4567 + if (count==0) { 1.4568 + __ move(destlo, valuelo); 1.4569 + __ move(desthi, valuehi); 1.4570 + } else if (count>=32) { 1.4571 + __ sll(desthi, valuelo, count-32); 1.4572 + __ move(destlo, R0); 1.4573 + } else { 1.4574 + __ srl(AT, valuelo, 32 - count); 1.4575 + __ sll(destlo, valuelo, count); 1.4576 + __ sll(desthi, valuehi, count); 1.4577 + __ orr(desthi, desthi, AT); 1.4578 + } 1.4579 + break; 1.4580 + 1.4581 + case lir_shr: 1.4582 + if (count==0) { 1.4583 + __ move(destlo, valuelo); 1.4584 + __ move(desthi, valuehi); 1.4585 + } else if (count>=32) { 1.4586 + __ sra(destlo, valuehi, count-32); 1.4587 + __ sra(desthi, valuehi, 31); 1.4588 + } else { 1.4589 + __ sll(AT, valuehi, 32 - count); 1.4590 + __ sra(desthi, valuehi, count); 1.4591 + __ srl(destlo, valuelo, count); 1.4592 + __ orr(destlo, destlo, AT); 1.4593 + } 1.4594 + break; 1.4595 + 1.4596 + case lir_ushr: 1.4597 + if (count==0) { 1.4598 + __ move(destlo, valuelo); 1.4599 + __ move(desthi, valuehi); 1.4600 + } else if (count>=32) { 1.4601 + __ sra(destlo, valuehi, count-32); 1.4602 + __ move(desthi, R0); 1.4603 + } else { 1.4604 + __ sll(AT, valuehi, 32 - count); 1.4605 + __ srl(desthi, valuehi, count); 1.4606 + __ srl(destlo, valuelo, count); 1.4607 + __ orr(destlo, destlo, AT); 1.4608 + } 1.4609 + break; 1.4610 + 1.4611 + default: ShouldNotReachHere(); 1.4612 + } 1.4613 +#endif 1.4614 + } else { 1.4615 + ShouldNotReachHere(); 1.4616 + } 1.4617 +} 1.4618 + 1.4619 +void LIR_Assembler::store_parameter(Register r, int offset_from_esp_in_words) { 1.4620 + assert(offset_from_esp_in_words >= 0, "invalid offset from esp"); 1.4621 + int offset_from_sp_in_bytes = offset_from_esp_in_words * BytesPerWord; 1.4622 + assert(offset_from_esp_in_words < frame_map()->reserved_argument_area_size(), "invalid offset"); 1.4623 + __ st_ptr(r, SP, offset_from_sp_in_bytes); 1.4624 +} 1.4625 + 1.4626 + 1.4627 +void LIR_Assembler::store_parameter(jint c, int offset_from_esp_in_words) { 1.4628 + assert(offset_from_esp_in_words >= 0, "invalid offset from esp"); 1.4629 + int offset_from_sp_in_bytes = offset_from_esp_in_words * BytesPerWord; 1.4630 + assert(offset_from_esp_in_words < frame_map()->reserved_argument_area_size(), "invalid offset"); 1.4631 + __ move(AT, c); 1.4632 + __ st_ptr(AT, SP, offset_from_sp_in_bytes); 1.4633 +} 1.4634 + 1.4635 +void LIR_Assembler::store_parameter(jobject o, int offset_from_esp_in_words) { 1.4636 + assert(offset_from_esp_in_words >= 0, "invalid offset from esp"); 1.4637 + int offset_from_sp_in_bytes = offset_from_esp_in_words * BytesPerWord; 1.4638 + assert(offset_from_sp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset"); 1.4639 + int oop_index = __ oop_recorder()->find_index(o); 1.4640 + RelocationHolder rspec = oop_Relocation::spec(oop_index); 1.4641 + __ relocate(rspec); 1.4642 +#ifndef _LP64 1.4643 + //by_css 1.4644 + __ lui(AT, Assembler::split_high((int)o)); 1.4645 + __ addiu(AT, AT, Assembler::split_low((int)o)); 1.4646 +#else 1.4647 + __ li48(AT, (long)o); 1.4648 +#endif 1.4649 + 1.4650 + __ st_ptr(AT, SP, offset_from_sp_in_bytes); 1.4651 + 1.4652 +} 1.4653 + 1.4654 + 1.4655 +// This code replaces a call to arraycopy; no exception may 1.4656 +// be thrown in this code, they must be thrown in the System.arraycopy 1.4657 +// activation frame; we could save some checks if this would not be the case 1.4658 +void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { 1.4659 + 1.4660 + 1.4661 + ciArrayKlass* default_type = op->expected_type(); 1.4662 + Register src = op->src()->as_register(); 1.4663 + Register dst = op->dst()->as_register(); 1.4664 + Register src_pos = op->src_pos()->as_register(); 1.4665 + Register dst_pos = op->dst_pos()->as_register(); 1.4666 + Register length = op->length()->as_register(); 1.4667 + Register tmp = T8; 1.4668 +#ifndef OPT_THREAD 1.4669 + Register java_thread = T8; 1.4670 +#else 1.4671 + Register java_thread = TREG; 1.4672 +#endif 1.4673 + CodeStub* stub = op->stub(); 1.4674 + 1.4675 + int flags = op->flags(); 1.4676 + BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL; 1.4677 + if (basic_type == T_ARRAY) basic_type = T_OBJECT; 1.4678 + 1.4679 + // if we don't know anything or it's an object array, just go through the generic arraycopy 1.4680 + if (default_type == NULL) { 1.4681 + Label done; 1.4682 + // save outgoing arguments on stack in case call to System.arraycopy is needed 1.4683 + // HACK ALERT. This code used to push the parameters in a hardwired fashion 1.4684 + // for interpreter calling conventions. Now we have to do it in new style conventions. 1.4685 + // For the moment until C1 gets the new register allocator I just force all the 1.4686 + // args to the right place (except the register args) and then on the back side 1.4687 + // reload the register args properly if we go slow path. Yuck 1.4688 + 1.4689 + // this is saved in the caller's reserved argument area 1.4690 + //FIXME, maybe It will change something in the stack; 1.4691 + // These are proper for the calling convention 1.4692 + //store_parameter(length, 2); 1.4693 + //store_parameter(dst_pos, 1); 1.4694 + //store_parameter(dst, 0); 1.4695 + 1.4696 + // these are just temporary placements until we need to reload 1.4697 + //store_parameter(src_pos, 3); 1.4698 + //store_parameter(src, 4); 1.4699 + assert(src == T0 && src_pos == A0, "mismatch in calling convention"); 1.4700 + // pass arguments: may push as this is not a safepoint; SP must be fix at each safepoint 1.4701 + 1.4702 + __ push(src); 1.4703 + __ push(dst); 1.4704 + __ push(src_pos); 1.4705 + __ push(dst_pos); 1.4706 + __ push(length); 1.4707 + 1.4708 + 1.4709 + // save SP and align 1.4710 +#ifndef OPT_THREAD 1.4711 + __ get_thread(java_thread); 1.4712 +#endif 1.4713 + __ st_ptr(SP, java_thread, in_bytes(JavaThread::last_Java_sp_offset())); 1.4714 +#ifndef _LP64 1.4715 + __ addi(SP, SP, (-5) * wordSize); 1.4716 + __ move(AT, -(StackAlignmentInBytes)); 1.4717 + __ andr(SP, SP, AT); 1.4718 + // push argument 1.4719 + __ sw(length, SP, 4 * wordSize); 1.4720 +#else 1.4721 + __ move(A4, length); 1.4722 +#endif 1.4723 + __ move(A3, dst_pos); 1.4724 + __ move(A2, dst); 1.4725 + __ move(A1, src_pos); 1.4726 + __ move(A0, src); 1.4727 + // make call 1.4728 + address entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy); 1.4729 + __ call(entry, relocInfo::runtime_call_type); 1.4730 + __ delayed()->nop(); 1.4731 + // restore SP 1.4732 +#ifndef OPT_THREAD 1.4733 + __ get_thread(java_thread); 1.4734 +#endif 1.4735 + __ ld_ptr(SP, java_thread, in_bytes(JavaThread::last_Java_sp_offset())); 1.4736 + __ super_pop(length); 1.4737 + __ super_pop(dst_pos); 1.4738 + __ super_pop(src_pos); 1.4739 + __ super_pop(dst); 1.4740 + __ super_pop(src); 1.4741 + 1.4742 + __ beq_far(V0, R0, *stub->continuation()); 1.4743 + __ delayed()->nop(); 1.4744 + 1.4745 + 1.4746 + __ b_far(*stub->entry()); 1.4747 + __ delayed()->nop(); 1.4748 + __ bind(*stub->continuation()); 1.4749 + return; 1.4750 + } 1.4751 + assert(default_type != NULL 1.4752 + && default_type->is_array_klass() 1.4753 + && default_type->is_loaded(), 1.4754 + "must be true at this point"); 1.4755 + 1.4756 + int elem_size = type2aelembytes(basic_type); 1.4757 + int shift_amount; 1.4758 + switch (elem_size) { 1.4759 + case 1 :shift_amount = 0; break; 1.4760 + case 2 :shift_amount = 1; break; 1.4761 + case 4 :shift_amount = 2; break; 1.4762 + case 8 :shift_amount = 3; break; 1.4763 + default:ShouldNotReachHere(); 1.4764 + } 1.4765 + 1.4766 + Address src_length_addr = Address(src, arrayOopDesc::length_offset_in_bytes()); 1.4767 + Address dst_length_addr = Address(dst, arrayOopDesc::length_offset_in_bytes()); 1.4768 + Address src_klass_addr = Address(src, oopDesc::klass_offset_in_bytes()); 1.4769 + Address dst_klass_addr = Address(dst, oopDesc::klass_offset_in_bytes()); 1.4770 + 1.4771 + // test for NULL 1.4772 + if (flags & LIR_OpArrayCopy::src_null_check) { 1.4773 + __ beq_far(src, R0, *stub->entry()); 1.4774 + __ delayed()->nop(); 1.4775 + } 1.4776 + if (flags & LIR_OpArrayCopy::dst_null_check) { 1.4777 + __ beq_far(dst, R0, *stub->entry()); 1.4778 + __ delayed()->nop(); 1.4779 + } 1.4780 + 1.4781 + // check if negative 1.4782 + if (flags & LIR_OpArrayCopy::src_pos_positive_check) { 1.4783 + __ bltz(src_pos, *stub->entry()); 1.4784 + __ delayed()->nop(); 1.4785 + } 1.4786 + if (flags & LIR_OpArrayCopy::dst_pos_positive_check) { 1.4787 + __ bltz(dst_pos, *stub->entry()); 1.4788 + __ delayed()->nop(); 1.4789 + } 1.4790 + if (flags & LIR_OpArrayCopy::length_positive_check) { 1.4791 + __ bltz(length, *stub->entry()); 1.4792 + __ delayed()->nop(); 1.4793 + } 1.4794 + 1.4795 + if (flags & LIR_OpArrayCopy::src_range_check) { 1.4796 + __ add(AT, src_pos, length); 1.4797 + __ lw(tmp, src_length_addr); 1.4798 + __ sltu(AT, tmp, AT); 1.4799 + __ bne_far(AT, R0, *stub->entry()); 1.4800 + __ delayed()->nop(); 1.4801 + } 1.4802 + if (flags & LIR_OpArrayCopy::dst_range_check) { 1.4803 + __ add(AT, dst_pos, length); 1.4804 + __ lw(tmp, dst_length_addr); 1.4805 + __ sltu(AT, tmp, AT); 1.4806 + __ bne_far(AT, R0, *stub->entry()); 1.4807 + __ delayed()->nop(); 1.4808 + } 1.4809 + 1.4810 + if (flags & LIR_OpArrayCopy::type_check) { 1.4811 + if (UseCompressedOops) { 1.4812 + __ lw(AT, src_klass_addr); 1.4813 + __ lw(tmp, dst_klass_addr); 1.4814 + } else { 1.4815 + __ ld(AT, src_klass_addr); 1.4816 + __ ld(tmp, dst_klass_addr); 1.4817 + } 1.4818 + __ bne_far(AT, tmp, *stub->entry()); 1.4819 + __ delayed()->nop(); 1.4820 + } 1.4821 + 1.4822 +#ifdef ASSERT 1.4823 + if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) { 1.4824 + // Sanity check the known type with the incoming class. For the 1.4825 + // primitive case the types must match exactly. For the object array 1.4826 + // case, if no type check is needed then the dst type must match the 1.4827 + // expected type and the src type is so subtype which we can't check. If 1.4828 + // a type check i needed then at this point the classes are known to be 1.4829 + // the same but again which don't know which type so we can't check them. 1.4830 + Label known_ok, halt; 1.4831 +//FIXME:wuhui. not finished. __ mov_metadata(tmp, default_type->constant_encoding()); 1.4832 +#ifdef _LP64 1.4833 + if (UseCompressedOops) { 1.4834 + __ encode_heap_oop(AT); 1.4835 + __ lw(tmp, dst_klass_addr); 1.4836 + } else 1.4837 +#endif 1.4838 + { 1.4839 + __ ld(tmp, dst_klass_addr); 1.4840 + } 1.4841 + if (basic_type != T_OBJECT) { 1.4842 + __ bne(AT, tmp, halt); 1.4843 + __ delayed()->nop(); 1.4844 + if (UseCompressedOops) { 1.4845 + __ lw(tmp, src_klass_addr); 1.4846 + } else { 1.4847 + __ ld(tmp, src_klass_addr); 1.4848 + } 1.4849 + __ beq(AT, tmp, known_ok); 1.4850 + __ delayed()->nop(); 1.4851 + } else { 1.4852 + if (UseCompressedOops) { 1.4853 + __ lw(tmp, dst_klass_addr); 1.4854 + } else { 1.4855 + __ ld(tmp, dst_klass_addr); 1.4856 + } 1.4857 + __ beq(AT, tmp, known_ok); 1.4858 + __ delayed()->nop(); 1.4859 + __ beq(src, dst, known_ok); 1.4860 + __ delayed()->nop(); 1.4861 + } 1.4862 + __ bind(halt); 1.4863 + __ stop("incorrect type information in arraycopy"); 1.4864 + __ bind(known_ok); 1.4865 + } 1.4866 +#endif 1.4867 + __ push(src); 1.4868 + __ push(dst); 1.4869 + __ push(src_pos); 1.4870 + __ push(dst_pos); 1.4871 + __ push(length); 1.4872 + 1.4873 + 1.4874 + assert(A0 != A1 && 1.4875 + A0 != length && 1.4876 + A1 != length, "register checks"); 1.4877 + __ move(AT, dst_pos); 1.4878 + if (shift_amount > 0 && basic_type != T_OBJECT) { 1.4879 +#ifndef _LP64 1.4880 + __ sll(A2, length, shift_amount); 1.4881 +#else 1.4882 + __ dsll(A2, length, shift_amount); 1.4883 +#endif 1.4884 + } else { 1.4885 + if (length!=A2) 1.4886 + __ move(A2, length); 1.4887 + } 1.4888 + __ move(A3, src_pos ); 1.4889 + assert(A0 != dst_pos && 1.4890 + A0 != dst && 1.4891 + dst_pos != dst, "register checks"); 1.4892 + 1.4893 + assert_different_registers(A0, dst_pos, dst); 1.4894 +#ifndef _LP64 1.4895 + __ sll(AT, AT, shift_amount); 1.4896 +#else 1.4897 + __ dsll(AT, AT, shift_amount); 1.4898 +#endif 1.4899 + __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(basic_type)); 1.4900 + __ add(A1, dst, AT); 1.4901 + 1.4902 +#ifndef _LP64 1.4903 + __ sll(AT, A3, shift_amount); 1.4904 +#else 1.4905 + __ dsll(AT, A3, shift_amount); 1.4906 +#endif 1.4907 + __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(basic_type)); 1.4908 + __ add(A0, src, AT); 1.4909 + 1.4910 + 1.4911 + 1.4912 + if (basic_type == T_OBJECT) { 1.4913 + __ call_VM_leaf(CAST_FROM_FN_PTR(address, Runtime1::oop_arraycopy), 3); 1.4914 + } else { 1.4915 + __ call_VM_leaf(CAST_FROM_FN_PTR(address, Runtime1::primitive_arraycopy), 3); 1.4916 + } 1.4917 + __ super_pop(length); 1.4918 + __ super_pop(dst_pos); 1.4919 + __ super_pop(src_pos); 1.4920 + __ super_pop(dst); 1.4921 + __ super_pop(src); 1.4922 + 1.4923 + __ bind(*stub->continuation()); 1.4924 +} 1.4925 + 1.4926 +void LIR_Assembler::emit_updatecrc32(LIR_OpUpdateCRC32* op) { 1.4927 + tty->print_cr("LIR_Assembler::emit_updatecrc32 unimplemented yet !"); 1.4928 + Unimplemented(); 1.4929 +} 1.4930 + 1.4931 +void LIR_Assembler::emit_lock(LIR_OpLock* op) { 1.4932 + Register obj = op->obj_opr()->as_register(); // may not be an oop 1.4933 + Register hdr = op->hdr_opr()->as_register(); 1.4934 + Register lock = op->lock_opr()->is_single_cpu() ? op->lock_opr()->as_register(): op->lock_opr()->as_register_lo(); 1.4935 + if (!UseFastLocking) { 1.4936 + __ b_far(*op->stub()->entry()); 1.4937 + } else if (op->code() == lir_lock) { 1.4938 + Register scratch = noreg; 1.4939 + if (UseBiasedLocking) { 1.4940 + scratch = op->scratch_opr()->as_register(); 1.4941 + } 1.4942 + assert(BasicLock::displaced_header_offset_in_bytes() == 0, 1.4943 + "lock_reg must point to the displaced header"); 1.4944 + // add debug info for NullPointerException only if one is possible 1.4945 + int null_check_offset = __ lock_object(hdr, obj, lock, scratch, *op->stub()->entry()); 1.4946 + if (op->info() != NULL) { 1.4947 + //add_debug_info_for_null_check_here(op->info()); 1.4948 + add_debug_info_for_null_check(null_check_offset,op->info()); 1.4949 + } 1.4950 + // done 1.4951 + } else if (op->code() == lir_unlock) { 1.4952 + assert(BasicLock::displaced_header_offset_in_bytes() == 0, 1.4953 + "lock_reg must point to the displaced header"); 1.4954 + __ unlock_object(hdr, obj, lock, *op->stub()->entry()); 1.4955 + } else { 1.4956 + Unimplemented(); 1.4957 + } 1.4958 + __ bind(*op->stub()->continuation()); 1.4959 +} 1.4960 + 1.4961 + 1.4962 + 1.4963 +void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { 1.4964 + ciMethod* method = op->profiled_method(); 1.4965 + int bci = op->profiled_bci(); 1.4966 + ciMethod* callee = op->profiled_callee(); 1.4967 + // Update counter for all call types 1.4968 + ciMethodData* md = method->method_data(); 1.4969 + if (md == NULL) { 1.4970 + bailout("out of memory building methodDataOop"); 1.4971 + return; 1.4972 + } 1.4973 + ciProfileData* data = md->bci_to_data(bci); 1.4974 + assert(data->is_CounterData(), "need CounterData for calls"); 1.4975 + assert(op->mdo()->is_single_cpu(), "mdo must be allocated"); 1.4976 + Register mdo = op->mdo()->as_register(); 1.4977 + 1.4978 + int oop_index = __ oop_recorder()->find_index(md->constant_encoding()); 1.4979 + RelocationHolder rspec = oop_Relocation::spec(oop_index); 1.4980 + __ relocate(rspec); 1.4981 +#ifndef _LP64 1.4982 + //by_css 1.4983 + __ lui(mdo, Assembler::split_high((int)md->constant_encoding())); 1.4984 + __ addiu(mdo, mdo, Assembler::split_low((int)md->constant_encoding())); 1.4985 +#else 1.4986 + __ li48(mdo, (long)md->constant_encoding()); 1.4987 +#endif 1.4988 + 1.4989 + Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); 1.4990 + __ lw(AT, counter_addr); 1.4991 + __ addi(AT,AT, DataLayout::counter_increment); 1.4992 + __ sw(AT,counter_addr); 1.4993 + 1.4994 + Bytecodes::Code bc = method->java_code_at_bci(bci); 1.4995 + const bool callee_is_static = callee->is_loaded() && callee->is_static(); 1.4996 + // Perform additional virtual call profiling for invokevirtual and 1.4997 + // invokeinterface bytecodes 1.4998 + if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) && 1.4999 + !callee_is_static && //required for optimized MH invokes 1.5000 + C1ProfileVirtualCalls) { 1.5001 + assert(op->recv()->is_single_cpu(), "recv must be allocated"); 1.5002 + Register recv = op->recv()->as_register(); 1.5003 + assert_different_registers(mdo, recv); 1.5004 + assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls"); 1.5005 + ciKlass* known_klass = op->known_holder(); 1.5006 + if (C1OptimizeVirtualCallProfiling && known_klass != NULL) { 1.5007 + // We know the type that will be seen at this call site; we can 1.5008 + // statically update the methodDataOop rather than needing to do 1.5009 + // dynamic tests on the receiver type 1.5010 + 1.5011 + // NOTE: we should probably put a lock around this search to 1.5012 + // avoid collisions by concurrent compilations 1.5013 + ciVirtualCallData* vc_data = (ciVirtualCallData*) data; 1.5014 + uint i; 1.5015 + for (i = 0; i < VirtualCallData::row_limit(); i++) { 1.5016 + ciKlass* receiver = vc_data->receiver(i); 1.5017 + if (known_klass->equals(receiver)) { 1.5018 + Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); 1.5019 + __ lw(AT, data_addr); 1.5020 + __ addi(AT, AT, DataLayout::counter_increment); 1.5021 + __ sw(AT, data_addr); 1.5022 + return; 1.5023 + } 1.5024 + } 1.5025 + 1.5026 + // Receiver type not found in profile data; select an empty slot 1.5027 + 1.5028 + // Note that this is less efficient than it should be because it 1.5029 + // always does a write to the receiver part of the 1.5030 + // VirtualCallData rather than just the first time 1.5031 + for (i = 0; i < VirtualCallData::row_limit(); i++) { 1.5032 + ciKlass* receiver = vc_data->receiver(i); 1.5033 + if (receiver == NULL) { 1.5034 + Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); 1.5035 + int oop_index = __ oop_recorder()->find_index(known_klass->constant_encoding()); 1.5036 + RelocationHolder rspec = oop_Relocation::spec(oop_index); 1.5037 + __ relocate(rspec); 1.5038 +#ifndef _LP64 1.5039 + //by_css 1.5040 + __ lui(AT, Assembler::split_high((int)known_klass->constant_encoding())); 1.5041 + __ addiu(AT, AT, Assembler::split_low((int)known_klass->constant_encoding())); 1.5042 +#else 1.5043 + __ li48(AT, (long)known_klass->constant_encoding()); 1.5044 +#endif 1.5045 + __ st_ptr(AT,recv_addr); 1.5046 + Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); 1.5047 + __ lw(AT, data_addr); 1.5048 + __ addi(AT, AT, DataLayout::counter_increment); 1.5049 + __ sw(AT, data_addr); 1.5050 + return; 1.5051 + } 1.5052 + } 1.5053 + } else { 1.5054 + //__ ld_ptr(recv, Address(recv, oopDesc::klass_offset_in_bytes())); 1.5055 + __ load_klass(recv, recv); 1.5056 + Label update_done; 1.5057 + uint i; 1.5058 + for (i = 0; i < VirtualCallData::row_limit(); i++) { 1.5059 + Label next_test; 1.5060 + // See if the receiver is receiver[n]. 1.5061 + __ ld_ptr(AT, Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)))); 1.5062 + __ bne(recv,AT,next_test); 1.5063 + __ delayed()->nop(); 1.5064 + Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); 1.5065 + __ lw(AT, data_addr); 1.5066 + __ addi(AT, AT, DataLayout::counter_increment); 1.5067 + __ sw(AT, data_addr); 1.5068 + __ b(update_done); 1.5069 + __ delayed()->nop(); 1.5070 + __ bind(next_test); 1.5071 + } 1.5072 + 1.5073 + // Didn't find receiver; find next empty slot and fill it in 1.5074 + for (i = 0; i < VirtualCallData::row_limit(); i++) { 1.5075 + Label next_test; 1.5076 + Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); 1.5077 + __ ld_ptr(AT, recv_addr); 1.5078 + __ bne(AT, R0, next_test); 1.5079 + __ delayed()->nop(); 1.5080 + __ st_ptr(recv, recv_addr); 1.5081 + __ move(AT,DataLayout::counter_increment); 1.5082 + __ sw(AT,Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)))); 1.5083 + if (i < (VirtualCallData::row_limit() - 1)) { 1.5084 + __ b(update_done); 1.5085 + __ delayed()->nop(); 1.5086 + } 1.5087 + __ bind(next_test); 1.5088 + } 1.5089 + 1.5090 + __ bind(update_done); 1.5091 + } 1.5092 + } 1.5093 +} 1.5094 + 1.5095 +void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { 1.5096 + // Newly added in OpenJDK 8 1.5097 + Unimplemented(); 1.5098 +} 1.5099 + 1.5100 +void LIR_Assembler::emit_delay(LIR_OpDelay*) { 1.5101 + Unimplemented(); 1.5102 +} 1.5103 + 1.5104 + 1.5105 +void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) { 1.5106 + if (dst->is_single_cpu()) 1.5107 + __ lea(dst->as_register(), frame_map()->address_for_monitor_lock(monitor_no)); 1.5108 + else if (dst->is_double_cpu()) 1.5109 + __ lea(dst->as_register_lo(), frame_map()->address_for_monitor_lock(monitor_no)); 1.5110 +} 1.5111 + 1.5112 +void LIR_Assembler::align_backward_branch_target() { 1.5113 +} 1.5114 + 1.5115 + 1.5116 +void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) { 1.5117 + if (left->is_single_cpu()) { 1.5118 + __ subu(dest->as_register(), R0, left->as_register()); 1.5119 + } else if (left->is_double_cpu()) { 1.5120 +#ifndef _LP64 1.5121 + Register lo = left->as_register_lo(); 1.5122 + Register hi = left->as_register_hi(); 1.5123 + Register dlo = dest->as_register_lo(); 1.5124 + Register dhi = dest->as_register_hi(); 1.5125 + assert(dlo != hi, "register checks"); 1.5126 + __ nor(dlo, R0, lo); 1.5127 + __ addiu(dlo, dlo, 1); 1.5128 + __ sltiu(AT, dlo, 1); 1.5129 + __ nor(dhi, R0, hi); 1.5130 + __ addu(dhi, dhi, AT); 1.5131 +#else 1.5132 + __ subu(dest->as_register_lo(), R0, left->as_register_lo()); 1.5133 +#endif 1.5134 + } else if (left->is_single_fpu()) { 1.5135 + //for mips , does it required ? 1.5136 + __ neg_s(dest->as_float_reg(), left->as_float_reg()); 1.5137 + } else if (left->is_double_fpu()) { 1.5138 + //for mips , does it required ? 1.5139 + __ neg_d(dest->as_double_reg(), left->as_double_reg()); 1.5140 + }else { 1.5141 + ShouldNotReachHere(); 1.5142 + } 1.5143 +} 1.5144 + 1.5145 + 1.5146 +void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest) { 1.5147 + assert(addr->is_address() && dest->is_register(), "check"); 1.5148 + Register reg = dest->as_register(); 1.5149 + __ lea(dest->as_register(), as_Address(addr->as_address_ptr())); 1.5150 +} 1.5151 + 1.5152 + 1.5153 +void LIR_Assembler::jobject2reg(jobject o, Register reg) { 1.5154 + if (o == NULL) { 1.5155 + // This seems wrong as we do not emit relocInfo 1.5156 + // for classes that are not loaded yet, i.e., they will be 1.5157 + // never GC'd 1.5158 +#ifndef _LP64 1.5159 +//by_css 1.5160 + __ lui(reg, Assembler::split_high((int)o)); 1.5161 + __ addiu(reg, reg, Assembler::split_low((int)o)); 1.5162 +#else 1.5163 + //__ li48(reg, (long)o); 1.5164 + __ li(reg, (long)o); 1.5165 +#endif 1.5166 + } else { 1.5167 + int oop_index = __ oop_recorder()->find_index(o); 1.5168 + RelocationHolder rspec = oop_Relocation::spec(oop_index); 1.5169 + __ relocate(rspec); 1.5170 +#ifndef _LP64 1.5171 +//by_css 1.5172 + __ lui(reg, Assembler::split_high((int)o)); 1.5173 + __ addiu(reg, reg, Assembler::split_low((int)o)); 1.5174 +#else 1.5175 + //__ li48(reg, (long)o); 1.5176 + __ li(reg, (long)o); 1.5177 +#endif 1.5178 + } 1.5179 +} 1.5180 + 1.5181 +void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info) { 1.5182 + assert(!tmp->is_valid(), "don't need temporary"); 1.5183 + __ call(dest, relocInfo::runtime_call_type); 1.5184 + __ delayed()->nop(); 1.5185 + if (info != NULL) { 1.5186 + add_call_info_here(info); 1.5187 + } 1.5188 +} 1.5189 + 1.5190 +/* by yyq 7/22/2009 1.5191 + * i don't know the register allocator will allocate long or double in two consecutive registers 1.5192 + * if the allocator do like this, the lws below should be removed and lds be used. 1.5193 + */ 1.5194 + 1.5195 +void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) { 1.5196 + assert(type == T_LONG, "only for volatile long fields"); 1.5197 + if (info != NULL) { 1.5198 + add_debug_info_for_null_check_here(info); 1.5199 + } 1.5200 + 1.5201 + if(src->is_register() && dest->is_address()) { 1.5202 + if(src->is_double_cpu()) { 1.5203 +#ifdef _LP64 1.5204 + __ sd(src->as_register_lo(), as_Address(dest->as_address_ptr())); 1.5205 +#else 1.5206 + __ sw(src->as_register_lo(), as_Address(dest->as_address_ptr())); 1.5207 + __ sw(src->as_register_hi(), as_Address(dest->as_address_ptr()).base(), 1.5208 + as_Address(dest->as_address_ptr()).disp() +4); 1.5209 +#endif 1.5210 + } else if (src->is_double_fpu()) { 1.5211 +#ifdef _LP64 1.5212 + __ sdc1(src->as_fpu_lo(), as_Address(dest->as_address_ptr())); 1.5213 +#else 1.5214 + __ swc1(src->as_fpu_lo(), as_Address(dest->as_address_ptr())); 1.5215 + __ swc1(src->as_fpu_hi(), as_Address(dest->as_address_ptr()).base(), 1.5216 + as_Address(dest->as_address_ptr()).disp() +4); 1.5217 +#endif 1.5218 + } else { 1.5219 + ShouldNotReachHere(); 1.5220 + } 1.5221 + } else if (src->is_address() && dest->is_register()){ 1.5222 + if(dest->is_double_cpu()) { 1.5223 +#ifdef _LP64 1.5224 + __ ld(dest->as_register_lo(), as_Address(src->as_address_ptr())); 1.5225 +#else 1.5226 + __ lw(dest->as_register_lo(), as_Address(src->as_address_ptr())); 1.5227 + __ lw(dest->as_register_hi(), as_Address(src->as_address_ptr()).base(), 1.5228 + as_Address(src->as_address_ptr()).disp() +4); 1.5229 +#endif 1.5230 + } else if (dest->is_double_fpu()) { 1.5231 +#ifdef _LP64 1.5232 + __ ldc1(dest->as_fpu_lo(), as_Address(src->as_address_ptr())); 1.5233 +#else 1.5234 + __ lwc1(dest->as_fpu_lo(), as_Address(src->as_address_ptr())); 1.5235 + __ lwc1(dest->as_fpu_hi(), as_Address(src->as_address_ptr()).base(), 1.5236 + as_Address(src->as_address_ptr()).disp() +4); 1.5237 +#endif 1.5238 + } else { 1.5239 + ShouldNotReachHere(); 1.5240 + } 1.5241 + } else { 1.5242 + ShouldNotReachHere(); 1.5243 + } 1.5244 +} 1.5245 + 1.5246 +#ifdef ASSERT 1.5247 +// emit run-time assertion 1.5248 +void LIR_Assembler::emit_assert(LIR_OpAssert* op) { 1.5249 + tty->print_cr("LIR_Assembler::emit_assert unimplemented yet!"); 1.5250 + Unimplemented(); 1.5251 +} 1.5252 +#endif 1.5253 + 1.5254 +void LIR_Assembler::membar() { 1.5255 + __ sync(); 1.5256 +} 1.5257 + 1.5258 +void LIR_Assembler::membar_acquire() { 1.5259 + __ sync(); 1.5260 +} 1.5261 + 1.5262 +void LIR_Assembler::membar_release() { 1.5263 + __ sync(); 1.5264 +} 1.5265 + 1.5266 +void LIR_Assembler::membar_loadload() { 1.5267 + // no-op 1.5268 + // //__ membar(Assembler::Membar_mask_bits(Assembler::loadload)); 1.5269 + } 1.5270 + 1.5271 +void LIR_Assembler::membar_storestore() { 1.5272 + // no-op 1.5273 + // //__ membar(Assembler::Membar_mask_bits(Assembler::storestore)); 1.5274 + } 1.5275 + 1.5276 +void LIR_Assembler::membar_loadstore() { 1.5277 + // no-op 1.5278 + // //__ membar(Assembler::Membar_mask_bits(Assembler::loadstore)); 1.5279 + } 1.5280 + 1.5281 +void LIR_Assembler::membar_storeload() { 1.5282 + //__ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad)); 1.5283 +} 1.5284 + 1.5285 + 1.5286 +void LIR_Assembler::get_thread(LIR_Opr result_reg) { 1.5287 + assert(result_reg->is_register(), "check"); 1.5288 +#ifndef OPT_THREAD 1.5289 + __ get_thread(NOT_LP64(result_reg->as_register()) LP64_ONLY(result_reg->as_register_lo())); 1.5290 +#else 1.5291 + __ move(NOT_LP64(result_reg->as_register()) LP64_ONLY(result_reg->as_register_lo()), TREG); 1.5292 +#endif 1.5293 +} 1.5294 + 1.5295 +void LIR_Assembler::peephole(LIR_List*) { 1.5296 + // do nothing for now 1.5297 +} 1.5298 + 1.5299 +void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp) { 1.5300 +/* assert(data == dest, "xchg/xadd uses only 2 operands"); 1.5301 + 1.5302 + if (data->type() == T_INT) { 1.5303 + if (code == lir_xadd) { 1.5304 + if (os::is_MP()) { 1.5305 + __ lock(); 1.5306 + } 1.5307 + __ xaddl(as_Address(src->as_address_ptr()), data->as_register()); 1.5308 + } else { 1.5309 + __ xchgl(data->as_register(), as_Address(src->as_address_ptr())); 1.5310 + } 1.5311 + } else if (data->is_oop()) { 1.5312 + assert (code == lir_xchg, "xadd for oops"); 1.5313 + Register obj = data->as_register(); 1.5314 +#ifdef _LP64 1.5315 + if (UseCompressedOops) { 1.5316 + __ encode_heap_oop(obj); 1.5317 + __ xchgl(obj, as_Address(src->as_address_ptr())); 1.5318 + __ decode_heap_oop(obj); 1.5319 + } else { 1.5320 + __ xchgptr(obj, as_Address(src->as_address_ptr())); 1.5321 + } 1.5322 +#else 1.5323 + __ xchgl(obj, as_Address(src->as_address_ptr())); 1.5324 +#endif 1.5325 + } else if (data->type() == T_LONG) { 1.5326 +#ifdef _LP64 1.5327 + assert(data->as_register_lo() == data->as_register_hi(), "should be a single register"); 1.5328 + if (code == lir_xadd) { 1.5329 + if (os::is_MP()) { 1.5330 + __ lock(); 1.5331 + } 1.5332 + __ xaddq(as_Address(src->as_address_ptr()), data->as_register_lo()); 1.5333 + } else { 1.5334 + __ xchgq(data->as_register_lo(), as_Address(src->as_address_ptr())); 1.5335 + } 1.5336 +#else 1.5337 + ShouldNotReachHere(); 1.5338 +#endif 1.5339 + } else { 1.5340 + ShouldNotReachHere(); 1.5341 + }*/ 1.5342 +} 1.5343 + 1.5344 +#undef __ 1.5345 + 1.5346 + 1.5347 + 1.5348 +