src/cpu/mips/vm/c1_LIRAssembler_mips.cpp

Wed, 29 Mar 2017 09:41:51 +0800

author
aoqi
date
Wed, 29 Mar 2017 09:41:51 +0800
changeset 392
4bfb40d1e17a
parent 1
2d8a650513c2
child 6880
52ea28d233d2
permissions
-rw-r--r--

#4662 TieredCompilation is turned off.
TieredCompilation is not supported yet.

aoqi@1 1 /*
aoqi@1 2 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@1 3 * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
aoqi@1 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@1 5 *
aoqi@1 6 * This code is free software; you can redistribute it and/or modify it
aoqi@1 7 * under the terms of the GNU General Public License version 2 only, as
aoqi@1 8 * published by the Free Software Foundation.
aoqi@1 9 *
aoqi@1 10 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@1 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@1 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@1 13 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@1 14 * accompanied this code).
aoqi@1 15 *
aoqi@1 16 * You should have received a copy of the GNU General Public License version
aoqi@1 17 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@1 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@1 19 *
aoqi@1 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@1 21 * or visit www.oracle.com if you need additional information or have any
aoqi@1 22 * questions.
aoqi@1 23 *
aoqi@1 24 */
aoqi@1 25
aoqi@1 26 #include "precompiled.hpp"
aoqi@1 27 #include "asm/macroAssembler.hpp"
aoqi@1 28 #include "asm/macroAssembler.inline.hpp"
aoqi@1 29 #include "c1/c1_Compilation.hpp"
aoqi@1 30 #include "c1/c1_LIRAssembler.hpp"
aoqi@1 31 #include "c1/c1_MacroAssembler.hpp"
aoqi@1 32 #include "c1/c1_Runtime1.hpp"
aoqi@1 33 #include "c1/c1_ValueStack.hpp"
aoqi@1 34 #include "ci/ciArrayKlass.hpp"
aoqi@1 35 #include "ci/ciInstance.hpp"
aoqi@1 36 #include "gc_interface/collectedHeap.hpp"
aoqi@1 37 #include "memory/barrierSet.hpp"
aoqi@1 38 #include "memory/cardTableModRefBS.hpp"
aoqi@1 39 #include "nativeInst_mips.hpp"
aoqi@1 40 #include "oops/objArrayKlass.hpp"
aoqi@1 41 #include "runtime/sharedRuntime.hpp"
aoqi@1 42 #define __ _masm->
aoqi@1 43
aoqi@1 44 static void select_different_registers(Register preserve,
aoqi@1 45 Register extra,
aoqi@1 46 Register &tmp1,
aoqi@1 47 Register &tmp2) {
aoqi@1 48 if (tmp1 == preserve) {
aoqi@1 49 assert_different_registers(tmp1, tmp2, extra);
aoqi@1 50 tmp1 = extra;
aoqi@1 51 } else if (tmp2 == preserve) {
aoqi@1 52 assert_different_registers(tmp1, tmp2, extra);
aoqi@1 53 tmp2 = extra;
aoqi@1 54 }
aoqi@1 55 assert_different_registers(preserve, tmp1, tmp2);
aoqi@1 56 }
aoqi@1 57
aoqi@1 58
aoqi@1 59
aoqi@1 60 static void select_different_registers(Register preserve,
aoqi@1 61 Register extra,
aoqi@1 62 Register &tmp1,
aoqi@1 63 Register &tmp2,
aoqi@1 64 Register &tmp3) {
aoqi@1 65 if (tmp1 == preserve) {
aoqi@1 66 assert_different_registers(tmp1, tmp2, tmp3, extra);
aoqi@1 67 tmp1 = extra;
aoqi@1 68 } else if (tmp2 == preserve) {
aoqi@1 69 tmp2 = extra;
aoqi@1 70 } else if (tmp3 == preserve) {
aoqi@1 71 assert_different_registers(tmp1, tmp2, tmp3, extra);
aoqi@1 72 tmp3 = extra;
aoqi@1 73 }
aoqi@1 74 assert_different_registers(preserve, tmp1, tmp2, tmp3);
aoqi@1 75 }
aoqi@1 76
aoqi@1 77 // need add method Assembler::is_simm16 in assembler_gs2.hpp
aoqi@1 78 bool LIR_Assembler::is_small_constant(LIR_Opr opr) {
aoqi@1 79 if (opr->is_constant()) {
aoqi@1 80 LIR_Const* constant = opr->as_constant_ptr();
aoqi@1 81 switch (constant->type()) {
aoqi@1 82 case T_INT: {
aoqi@1 83 jint value = constant->as_jint();
aoqi@1 84 return Assembler::is_simm16(value);
aoqi@1 85 }
aoqi@1 86 default:
aoqi@1 87 return false;
aoqi@1 88 }
aoqi@1 89 }
aoqi@1 90 return false;
aoqi@1 91 }
aoqi@1 92
aoqi@1 93 //FIXME, which register should be used?
aoqi@1 94 LIR_Opr LIR_Assembler::receiverOpr() {
aoqi@1 95 return FrameMap::_t0_oop_opr;
aoqi@1 96 }
aoqi@1 97 /*
aoqi@1 98 LIR_Opr LIR_Assembler::incomingReceiverOpr() {
aoqi@1 99 return receiverOpr();
aoqi@1 100 }*/
aoqi@1 101
aoqi@1 102 LIR_Opr LIR_Assembler::osrBufferPointer() {
aoqi@1 103 #ifdef _LP64
aoqi@1 104 Register r = receiverOpr()->as_register();
aoqi@1 105 return FrameMap::as_long_opr(r, r);
aoqi@1 106 #else
aoqi@1 107 return FrameMap::as_opr(receiverOpr()->as_register());
aoqi@1 108 #endif
aoqi@1 109 }
aoqi@1 110
aoqi@1 111 //--------------fpu register translations-----------------------
aoqi@1 112 // FIXME:I do not know what's to do for mips fpu
aoqi@1 113
aoqi@1 114 address LIR_Assembler::float_constant(float f) {
aoqi@1 115 address const_addr = __ float_constant(f);
aoqi@1 116 if (const_addr == NULL) {
aoqi@1 117 bailout("const section overflow");
aoqi@1 118 return __ code()->consts()->start();
aoqi@1 119 } else {
aoqi@1 120 return const_addr;
aoqi@1 121 }
aoqi@1 122 }
aoqi@1 123
aoqi@1 124
aoqi@1 125 address LIR_Assembler::double_constant(double d) {
aoqi@1 126 address const_addr = __ double_constant(d);
aoqi@1 127 if (const_addr == NULL) {
aoqi@1 128 bailout("const section overflow");
aoqi@1 129 return __ code()->consts()->start();
aoqi@1 130 } else {
aoqi@1 131 return const_addr;
aoqi@1 132 }
aoqi@1 133 }
aoqi@1 134
aoqi@1 135
aoqi@1 136
aoqi@1 137
aoqi@1 138
aoqi@1 139 void LIR_Assembler::reset_FPU() {
aoqi@1 140 Unimplemented();
aoqi@1 141 }
aoqi@1 142
aoqi@1 143
aoqi@1 144 void LIR_Assembler::set_24bit_FPU() {
aoqi@1 145 Unimplemented();
aoqi@1 146 }
aoqi@1 147
aoqi@1 148 //FIXME.
aoqi@1 149 void LIR_Assembler::fpop() {
aoqi@1 150 // do nothing
aoqi@1 151 }
aoqi@1 152 void LIR_Assembler::fxch(int i) {
aoqi@1 153 // do nothing
aoqi@1 154 }
aoqi@1 155 void LIR_Assembler::fld(int i) {
aoqi@1 156 // do nothing
aoqi@1 157 }
aoqi@1 158 void LIR_Assembler::ffree(int i) {
aoqi@1 159 // do nothing
aoqi@1 160 }
aoqi@1 161
aoqi@1 162 void LIR_Assembler::breakpoint() {
aoqi@1 163 __ brk(17);
aoqi@1 164 }
aoqi@1 165 //FIXME, opr can not be float?
aoqi@1 166 void LIR_Assembler::push(LIR_Opr opr) {
aoqi@1 167 if (opr->is_single_cpu()) {
aoqi@1 168 __ push_reg(opr->as_register());
aoqi@1 169 } else if (opr->is_double_cpu()) {
aoqi@1 170 __ push_reg(opr->as_register_hi());
aoqi@1 171 __ push_reg(opr->as_register_lo());
aoqi@1 172 } else if (opr->is_stack()) {
aoqi@1 173 __ push_addr(frame_map()->address_for_slot(opr->single_stack_ix()));
aoqi@1 174 } else if (opr->is_constant()) {
aoqi@1 175 LIR_Const* const_opr = opr->as_constant_ptr();
aoqi@1 176 if (const_opr->type() == T_OBJECT) {
aoqi@1 177 __ push_oop(const_opr->as_jobject());
aoqi@1 178 } else if (const_opr->type() == T_INT) {
aoqi@1 179 __ push_jint(const_opr->as_jint());
aoqi@1 180 } else {
aoqi@1 181 ShouldNotReachHere();
aoqi@1 182 }
aoqi@1 183 } else {
aoqi@1 184 ShouldNotReachHere();
aoqi@1 185 }
aoqi@1 186 }
aoqi@1 187
aoqi@1 188 void LIR_Assembler::pop(LIR_Opr opr) {
aoqi@1 189 if (opr->is_single_cpu() ) {
aoqi@1 190 __ pop(opr->as_register());
aoqi@1 191 } else {
aoqi@1 192 assert(false, "Must be single word register or floating-point register");
aoqi@1 193 }
aoqi@1 194 }
aoqi@1 195
aoqi@1 196
aoqi@1 197 Address LIR_Assembler::as_Address(LIR_Address* addr) {
aoqi@1 198 #ifndef _LP64
aoqi@1 199 Register reg = addr->base()->as_register();
aoqi@1 200 #else
aoqi@1 201 //FIXME aoqi
aoqi@1 202 Register reg = addr->base()->is_single_cpu()? addr->base()->as_register() : addr->base()->as_register_lo();
aoqi@1 203 #endif
aoqi@1 204 // now we need this for parameter pass
aoqi@1 205 return Address(reg, addr->disp());
aoqi@1 206 }
aoqi@1 207
aoqi@1 208
aoqi@1 209 Address LIR_Assembler::as_Address_lo(LIR_Address* addr) {
aoqi@1 210 return as_Address(addr);
aoqi@1 211 }
aoqi@1 212
aoqi@1 213
aoqi@1 214 Address LIR_Assembler::as_Address_hi(LIR_Address* addr) {
aoqi@1 215 Register reg = addr->base()->as_register();
aoqi@1 216 return Address(reg, addr->disp()+longSize/2);
aoqi@1 217 }
aoqi@1 218
aoqi@1 219
aoqi@1 220 //void LIR_Assembler::osr_entry(IRScope* scope, int number_of_locks, Label* continuation, int osr_bci) {
aoqi@1 221 void LIR_Assembler::osr_entry() {
aoqi@1 222 // assert(scope->is_top_scope(), "inlined OSR not yet implemented");
aoqi@1 223 offsets()->set_value(CodeOffsets::OSR_Entry, code_offset());
aoqi@1 224 BlockBegin* osr_entry = compilation()->hir()->osr_entry();
aoqi@1 225 ValueStack* entry_state = osr_entry->state();
aoqi@1 226 int number_of_locks = entry_state->locks_size();
aoqi@1 227
aoqi@1 228 // we jump here if osr happens with the interpreter
aoqi@1 229 // state set up to continue at the beginning of the
aoqi@1 230 // loop that triggered osr - in particular, we have
aoqi@1 231 // the following registers setup:
aoqi@1 232 //
aoqi@1 233 // S7: interpreter locals pointer
aoqi@1 234 // V1: interpreter locks pointer
aoqi@1 235 // RA: return address
aoqi@1 236 //T0: OSR buffer
aoqi@1 237 // build frame
aoqi@1 238 // ciMethod* m = scope->method();
aoqi@1 239 ciMethod* m = compilation()->method();
aoqi@1 240 __ build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes());
aoqi@1 241
aoqi@1 242 // OSR buffer is
aoqi@1 243 //
aoqi@1 244 // locals[nlocals-1..0]
aoqi@1 245 // monitors[0..number_of_locks]
aoqi@1 246 //
aoqi@1 247 // locals is a direct copy of the interpreter frame so in the osr buffer
aoqi@1 248 // so first slot in the local array is the last local from the interpreter
aoqi@1 249 // and last slot is local[0] (receiver) from the interpreter
aoqi@1 250 //
aoqi@1 251 // Similarly with locks. The first lock slot in the osr buffer is the nth lock
aoqi@1 252 // from the interpreter frame, the nth lock slot in the osr buffer is 0th lock
aoqi@1 253 // in the interpreter frame (the method lock if a sync method)
aoqi@1 254
aoqi@1 255 // Initialize monitors in the compiled activation.
aoqi@1 256 // T0: pointer to osr buffer
aoqi@1 257 //
aoqi@1 258 // All other registers are dead at this point and the locals will be
aoqi@1 259 // copied into place by code emitted in the IR.
aoqi@1 260
aoqi@1 261 Register OSR_buf = osrBufferPointer()->as_pointer_register();
aoqi@1 262
aoqi@1 263
aoqi@1 264 // note: we do osr only if the expression stack at the loop beginning is empty,
aoqi@1 265 // in which case the spill area is empty too and we don't have to setup
aoqi@1 266 // spilled locals
aoqi@1 267 //
aoqi@1 268 // copy monitors
aoqi@1 269 // V1: pointer to locks
aoqi@1 270 {
aoqi@1 271 assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
aoqi@1 272 int monitor_offset = BytesPerWord * method()->max_locals()+
aoqi@1 273 (BasicObjectLock::size() * BytesPerWord) * (number_of_locks - 1);
aoqi@1 274 for (int i = 0; i < number_of_locks; i++) {
aoqi@1 275 int slot_offset =monitor_offset - (i * BasicObjectLock::size())*BytesPerWord;
aoqi@1 276 #ifdef ASSERT
aoqi@1 277 {
aoqi@1 278 Label L;
aoqi@1 279 //__ lw(AT, V1, slot_offset * BytesPerWord + BasicObjectLock::obj_offset_in_bytes());
aoqi@1 280 __ ld_ptr(AT, OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes());
aoqi@1 281 __ bne(AT, R0, L);
aoqi@1 282 __ delayed()->nop();
aoqi@1 283 __ stop("locked object is NULL");
aoqi@1 284 __ bind(L);
aoqi@1 285 }
aoqi@1 286 #endif
aoqi@1 287 __ ld_ptr(AT, OSR_buf, slot_offset + BasicObjectLock::lock_offset_in_bytes());
aoqi@1 288 __ st_ptr(AT, frame_map()->address_for_monitor_lock(i));
aoqi@1 289 __ ld_ptr(AT, OSR_buf, slot_offset + BasicObjectLock::obj_offset_in_bytes());
aoqi@1 290 __ st_ptr(AT, frame_map()->address_for_monitor_object(i));
aoqi@1 291 }
aoqi@1 292 }
aoqi@1 293 }
aoqi@1 294
aoqi@1 295
aoqi@1 296 int LIR_Assembler::check_icache() {
aoqi@1 297 Register receiver = FrameMap::receiver_opr->as_register();
aoqi@1 298 Register ic_klass = IC_Klass;
aoqi@1 299
aoqi@1 300 /*const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
aoqi@1 301 const bool do_post_padding = VerifyOops || UseCompressedOops;
aoqi@1 302 if (!do_post_padding) {
aoqi@1 303 // insert some nops so that the verified entry point is aligned on CodeEntryAlignment
aoqi@1 304 while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) {
aoqi@1 305 __ nop();
aoqi@1 306 }
aoqi@1 307 }*/
aoqi@1 308
aoqi@1 309 int offset = __ offset();
aoqi@1 310 __ inline_cache_check(receiver, IC_Klass);
aoqi@1 311 __ align(CodeEntryAlignment);
aoqi@1 312 return offset;
aoqi@1 313
aoqi@1 314
aoqi@1 315 }
aoqi@1 316
aoqi@1 317 void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo* info) {
aoqi@1 318 jobject o = NULL;
aoqi@1 319 PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_klass_id);
aoqi@1 320 int oop_index = __ oop_recorder()->allocate_oop_index(o);
aoqi@1 321 RelocationHolder rspec = oop_Relocation::spec(oop_index);
aoqi@1 322 __ relocate(rspec);
aoqi@1 323 #ifndef _LP64
aoqi@1 324 //by_css
aoqi@1 325 __ lui(reg, Assembler::split_high((int)o));
aoqi@1 326 __ addiu(reg, reg, Assembler::split_low((int)o));
aoqi@1 327 #else
aoqi@1 328 //li may not pass NativeMovConstReg::verify. see nativeMovConstReg_at(pc_start()); in PatchingStub::install. by aoqi
aoqi@1 329 __ li48(reg, (long)o);
aoqi@1 330 #endif
aoqi@1 331 // patching_epilog(patch, LIR_Op1::patch_normal, noreg, info);
aoqi@1 332 patching_epilog(patch, lir_patch_normal, reg, info);
aoqi@1 333 }
aoqi@1 334
aoqi@1 335
aoqi@1 336 void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register unused, int monitor_no, Register exception) {
aoqi@1 337
aoqi@1 338 if (exception->is_valid()) {
aoqi@1 339 // preserve exception
aoqi@1 340 // note: the monitor_exit runtime call is a leaf routine
aoqi@1 341 // and cannot block => no GC can happen
aoqi@1 342 // The slow case (MonitorAccessStub) uses the first two stack slots
aoqi@1 343 // ([SP+0] and [SP+4]), therefore we store the exception at [esp+8]
aoqi@1 344 __ st_ptr(exception, SP, 2 * wordSize);
aoqi@1 345 }
aoqi@1 346
aoqi@1 347 Register obj_reg = obj_opr->as_register();
aoqi@1 348 Register lock_reg = lock_opr->as_register();
aoqi@1 349
aoqi@1 350 // compute pointer to BasicLock
aoqi@1 351 //Address lock_addr = frame_map()->address_for_monitor_lock_index(monitor_no);
aoqi@1 352 Address lock_addr = frame_map()->address_for_monitor_lock(monitor_no);
aoqi@1 353 __ lea(lock_reg, lock_addr);
aoqi@1 354 // unlock object
aoqi@1 355 MonitorAccessStub* slow_case = new MonitorExitStub(lock_opr, true, monitor_no);
aoqi@1 356 // temporary fix: must be created after exceptionhandler, therefore as call stub
aoqi@1 357 _slow_case_stubs->append(slow_case);
aoqi@1 358 if (UseFastLocking) {
aoqi@1 359 // try inlined fast unlocking first, revert to slow locking if it fails
aoqi@1 360 // note: lock_reg points to the displaced header since the displaced header offset is 0!
aoqi@1 361 assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
aoqi@1 362 __ unlock_object(NOREG, obj_reg, lock_reg, *slow_case->entry());
aoqi@1 363 } else {
aoqi@1 364 // always do slow unlocking
aoqi@1 365 // note: the slow unlocking code could be inlined here, however if we use
aoqi@1 366 // slow unlocking, speed doesn't matter anyway and this solution is
aoqi@1 367 // simpler and requires less duplicated code - additionally, the
aoqi@1 368 // slow unlocking code is the same in either case which simplifies
aoqi@1 369 // debugging
aoqi@1 370 __ b_far(*slow_case->entry());
aoqi@1 371 __ delayed()->nop();
aoqi@1 372 }
aoqi@1 373 // done
aoqi@1 374 __ bind(*slow_case->continuation());
aoqi@1 375
aoqi@1 376 if (exception->is_valid()) {
aoqi@1 377 // restore exception
aoqi@1 378 __ ld_ptr(exception, SP, 2 * wordSize);
aoqi@1 379 }
aoqi@1 380 }
aoqi@1 381
aoqi@1 382 // This specifies the esp decrement needed to build the frame
aoqi@1 383 int LIR_Assembler::initial_frame_size_in_bytes() const {
aoqi@1 384 // if rounding, must let FrameMap know!
aoqi@1 385 // return (frame_map()->framesize() - 2) * BytesPerWord; // subtract two words to account for return address and link
aoqi@1 386 return (frame_map()->framesize() - (2*VMRegImpl::slots_per_word)) * VMRegImpl::stack_slot_size;
aoqi@1 387 }
aoqi@1 388
aoqi@1 389 int LIR_Assembler::emit_exception_handler() {
aoqi@1 390 // if the last instruction is a call (typically to do a throw which
aoqi@1 391 // is coming at the end after block reordering) the return address
aoqi@1 392 // must still point into the code area in order to avoid assertion
aoqi@1 393 // failures when searching for the corresponding bci => add a nop
aoqi@1 394 // (was bug 5/14/1999 - gri)
aoqi@1 395 // Lazy deopt bug 4932387. If last instruction is a call then we
aoqi@1 396 // need an area to patch where we won't overwrite the exception
aoqi@1 397 // handler. This means we need 5 bytes. Could use a fat_nop
aoqi@1 398 // but since this never gets executed it doesn't really make
aoqi@1 399 // much difference.
aoqi@1 400 //
aoqi@1 401 for (int i = 0; i < (NativeCall::instruction_size/BytesPerInstWord + 1) ; i++ ) {
aoqi@1 402 __ nop();
aoqi@1 403 }
aoqi@1 404
aoqi@1 405 // generate code for exception handler
aoqi@1 406 address handler_base = __ start_a_stub(exception_handler_size);
aoqi@1 407 if (handler_base == NULL) {
aoqi@1 408 //no enough space
aoqi@1 409 bailout("exception handler overflow");
aoqi@1 410 return -1;
aoqi@1 411 }
aoqi@1 412
aoqi@1 413
aoqi@1 414
aoqi@1 415 //compilation()->offsets()->set_value(CodeOffsets::Exceptions, code_offset());
aoqi@1 416 // if the method does not have an exception handler, then there is
aoqi@1 417 // no reason to search for one
aoqi@1 418 //if (compilation()->has_exception_handlers() || JvmtiExport::can_post_exceptions()) {
aoqi@1 419 // the exception oop and pc are in V0 and V1
aoqi@1 420 // no other registers need to be preserved, so invalidate them
aoqi@1 421 // check that there is really an exception
aoqi@1 422 // __ verify_not_null_oop(V0);
aoqi@1 423
aoqi@1 424 // search an exception handler (V0: exception oop, V1: throwing pc)
aoqi@1 425 // __ call(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id),
aoqi@1 426 // relocInfo::runtime_call_type);
aoqi@1 427 // __ delayed()->nop();
aoqi@1 428 // if the call returns here, then the exception handler for particular
aoqi@1 429 // exception doesn't exist -> unwind activation and forward exception to caller
aoqi@1 430 // }
aoqi@1 431 int offset = code_offset();
aoqi@1 432
aoqi@1 433 // the exception oop is in V0
aoqi@1 434 // no other registers need to be preserved, so invalidate them
aoqi@1 435 // check that there is really an exception
aoqi@1 436 __ verify_not_null_oop(V0);
aoqi@1 437 //FIXME:wuhui??
aoqi@1 438 //__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_from_callee_id)));
aoqi@1 439 //__ delayed()->nop();
aoqi@1 440 __ should_not_reach_here();
aoqi@1 441 guarantee(code_offset() - offset <= exception_handler_size, "overflow");
aoqi@1 442 __ end_a_stub();
aoqi@1 443 return offset;
aoqi@1 444
aoqi@1 445 // unlock the receiver/klass if necessary
aoqi@1 446 // V0: exception
aoqi@1 447 // ciMethod* method = compilation()->method();
aoqi@1 448 // if (method->is_synchronized() && GenerateSynchronizationCode) {
aoqi@1 449 //#ifndef _LP64
aoqi@1 450 //by_css
aoqi@1 451 // monitorexit(FrameMap::_t0_oop_opr, FrameMap::_t6_opr, NOREG, 0, V0);
aoqi@1 452 //#else
aoqi@1 453 // monitorexit(FrameMap::_t0_oop_opr, FrameMap::_a6_opr, NOREG, 0, V0);
aoqi@1 454 //#endif
aoqi@1 455 // }
aoqi@1 456
aoqi@1 457 // unwind activation and forward exception to caller
aoqi@1 458 // V0: exception
aoqi@1 459 // __ jmp(Runtime1::entry_for(Runtime1::unwind_exception_id),
aoqi@1 460 // relocInfo::runtime_call_type);
aoqi@1 461 // __ delayed()->nop();
aoqi@1 462 // __ end_a_stub();
aoqi@1 463 }
aoqi@1 464
aoqi@1 465 // Emit the code to remove the frame from the stack in the exception
aoqi@1 466 // // unwind path.
aoqi@1 467 int LIR_Assembler::emit_unwind_handler() {
aoqi@1 468 #ifndef PRODUCT
aoqi@1 469 if (CommentedAssembly) {
aoqi@1 470 _masm->block_comment("Unwind handler");
aoqi@1 471 }
aoqi@1 472 #endif
aoqi@1 473
aoqi@1 474 int offset = code_offset();
aoqi@1 475 /* // Fetch the exception from TLS and clear out exception related thread state
aoqi@1 476 __ get_thread(rsi);
aoqi@1 477 __ movptr(rax, Address(rsi, JavaThread::exception_oop_offset()));
aoqi@1 478 __ movptr(Address(rsi, JavaThread::exception_oop_offset()), (intptr_t)NULL_WORD);
aoqi@1 479 __ movptr(Address(rsi, JavaThread::exception_pc_offset()), (intptr_t)NULL_WORD);
aoqi@1 480
aoqi@1 481 __ bind(_unwind_handler_entry);
aoqi@1 482 __ verify_not_null_oop(rax);
aoqi@1 483 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {
aoqi@1 484 __ mov(rsi, rax); // Preserve the exception
aoqi@1 485 }
aoqi@1 486 // Preform needed unlocking
aoqi@1 487 MonitorExitStub* stub = NULL;
aoqi@1 488 if (method()->is_synchronized()) {
aoqi@1 489 monitor_address(0, FrameMap::rax_opr);
aoqi@1 490 stub = new MonitorExitStub(FrameMap::rax_opr, true, 0);
aoqi@1 491 __ unlock_object(rdi, rbx, rax, *stub->entry());
aoqi@1 492 __ bind(*stub->continuation());
aoqi@1 493 }
aoqi@1 494
aoqi@1 495 if (compilation()->env()->dtrace_method_probes()) {
aoqi@1 496 __ get_thread(rax);
aoqi@1 497 __ movptr(Address(rsp, 0), rax);
aoqi@1 498 __ mov_metadata(Address(rsp, sizeof(void*)), method()->constant_encoding());
aoqi@1 499 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit)));
aoqi@1 500 }
aoqi@1 501
aoqi@1 502 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {
aoqi@1 503 __ mov(rax, rsi); // Restore the exception
aoqi@1 504 }
aoqi@1 505
aoqi@1 506 // remove the activation and dispatch to the unwind handler
aoqi@1 507 __ remove_frame(initial_frame_size_in_bytes());
aoqi@1 508 __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id)));
aoqi@1 509
aoqi@1 510 // Emit the slow path assembly
aoqi@1 511 if (stub != NULL) {
aoqi@1 512 stub->emit_code(this);
aoqi@1 513 }
aoqi@1 514 */
aoqi@1 515 return offset;
aoqi@1 516 }
aoqi@1 517
aoqi@1 518
aoqi@1 519 int LIR_Assembler::emit_deopt_handler() {
aoqi@1 520 // if the last instruction is a call (typically to do a throw which
aoqi@1 521 // is coming at the end after block reordering) the return address
aoqi@1 522 // must still point into the code area in order to avoid assertion
aoqi@1 523 // failures when searching for the corresponding bci => add a nop
aoqi@1 524 // (was bug 5/14/1999 - gri)
aoqi@1 525
aoqi@1 526 __ nop();
aoqi@1 527
aoqi@1 528 // generate code for exception handler
aoqi@1 529 address handler_base = __ start_a_stub(deopt_handler_size);
aoqi@1 530 if (handler_base == NULL) {
aoqi@1 531 // not enough space left for the handler
aoqi@1 532 bailout("deopt handler overflow");
aoqi@1 533 return -1;
aoqi@1 534 }
aoqi@1 535 int offset = code_offset();
aoqi@1 536
aoqi@1 537 // compilation()->offsets()->set_value(CodeOffsets::Deopt, code_offset());
aoqi@1 538
aoqi@1 539 __ call(SharedRuntime::deopt_blob()->unpack());
aoqi@1 540 __ delayed()->nop();
aoqi@1 541
aoqi@1 542 guarantee(code_offset() - offset <= deopt_handler_size, "overflow");
aoqi@1 543 __ end_a_stub();
aoqi@1 544 return offset;
aoqi@1 545
aoqi@1 546 }
aoqi@1 547
aoqi@1 548
aoqi@1 549 // Optimized Library calls
aoqi@1 550 // This is the fast version of java.lang.String.compare; it has not
aoqi@1 551 // OSR-entry and therefore, we generate a slow version for OSR's
aoqi@1 552 //void LIR_Assembler::emit_string_compare(IRScope* scope) {
aoqi@1 553 void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, CodeEmitInfo* info) {
aoqi@1 554 // get two string object in T0&T1
aoqi@1 555 //receiver already in T0
aoqi@1 556 __ ld_ptr(T1, arg1->as_register());
aoqi@1 557 //__ ld_ptr(T2, T0, java_lang_String::value_offset_in_bytes()); //value, T_CHAR array
aoqi@1 558 __ load_heap_oop(T2, Address(T0, java_lang_String::value_offset_in_bytes()));
aoqi@1 559 __ ld_ptr(AT, T0, java_lang_String::offset_offset_in_bytes()); //offset
aoqi@1 560 __ shl(AT, 1);
aoqi@1 561 __ add(T2, T2, AT);
aoqi@1 562 __ addi(T2, T2, arrayOopDesc::base_offset_in_bytes(T_CHAR));
aoqi@1 563 // Now T2 is the address of the first char in first string(T0)
aoqi@1 564
aoqi@1 565 add_debug_info_for_null_check_here(info);
aoqi@1 566 //__ ld_ptr(T3, T1, java_lang_String::value_offset_in_bytes());
aoqi@1 567 __ load_heap_oop(T3, Address(T1, java_lang_String::value_offset_in_bytes()));
aoqi@1 568 __ ld_ptr(AT, T1, java_lang_String::offset_offset_in_bytes());
aoqi@1 569 __ shl(AT, 1);
aoqi@1 570 __ add(T3, T3, AT);
aoqi@1 571 __ addi(T3, T3, arrayOopDesc::base_offset_in_bytes(T_CHAR));
aoqi@1 572 // Now T3 is the address of the first char in second string(T1)
aoqi@1 573
aoqi@1 574 #ifndef _LP64
aoqi@1 575 //by_css
aoqi@1 576 // compute minimum length (in T4) and difference of lengths (V0)
aoqi@1 577 Label L;
aoqi@1 578 __ lw (T4, Address(T0, java_lang_String::count_offset_in_bytes()));
aoqi@1 579 // the length of the first string(T0)
aoqi@1 580 __ lw (T5, Address(T1, java_lang_String::count_offset_in_bytes()));
aoqi@1 581 // the length of the second string(T1)
aoqi@1 582
aoqi@1 583 __ subu(V0, T4, T5);
aoqi@1 584 __ blez(V0, L);
aoqi@1 585 __ delayed()->nop();
aoqi@1 586 __ move (T4, T5);
aoqi@1 587 __ bind (L);
aoqi@1 588
aoqi@1 589 Label Loop, haveResult, LoopEnd;
aoqi@1 590 __ bind(Loop);
aoqi@1 591 __ beq(T4, R0, LoopEnd);
aoqi@1 592 __ delayed();
aoqi@1 593
aoqi@1 594 __ addi(T2, T2, 2);
aoqi@1 595
aoqi@1 596 // compare current character
aoqi@1 597 __ lhu(T5, T2, -2);
aoqi@1 598 __ lhu(T6, T3, 0);
aoqi@1 599 __ bne(T5, T6, haveResult);
aoqi@1 600 __ delayed();
aoqi@1 601
aoqi@1 602 __ addi(T3, T3, 2);
aoqi@1 603
aoqi@1 604 __ b(Loop);
aoqi@1 605 __ delayed()->addi(T4, T4, -1);
aoqi@1 606
aoqi@1 607 __ bind(haveResult);
aoqi@1 608 __ subu(V0, T5, T6);
aoqi@1 609
aoqi@1 610 __ bind(LoopEnd);
aoqi@1 611 #else
aoqi@1 612 // compute minimum length (in T4) and difference of lengths (V0)
aoqi@1 613 Label L;
aoqi@1 614 __ lw (A4, Address(T0, java_lang_String::count_offset_in_bytes()));
aoqi@1 615 // the length of the first string(T0)
aoqi@1 616 __ lw (A5, Address(T1, java_lang_String::count_offset_in_bytes()));
aoqi@1 617 // the length of the second string(T1)
aoqi@1 618
aoqi@1 619 __ dsubu(V0, A4, A5);
aoqi@1 620 __ blez(V0, L);
aoqi@1 621 __ delayed()->nop();
aoqi@1 622 __ move (A4, A5);
aoqi@1 623 __ bind (L);
aoqi@1 624
aoqi@1 625 Label Loop, haveResult, LoopEnd;
aoqi@1 626 __ bind(Loop);
aoqi@1 627 __ beq(A4, R0, LoopEnd);
aoqi@1 628 __ delayed();
aoqi@1 629
aoqi@1 630 __ daddi(T2, T2, 2);
aoqi@1 631
aoqi@1 632 // compare current character
aoqi@1 633 __ lhu(A5, T2, -2);
aoqi@1 634 __ lhu(A6, T3, 0);
aoqi@1 635 __ bne(A5, A6, haveResult);
aoqi@1 636 __ delayed();
aoqi@1 637
aoqi@1 638 __ daddi(T3, T3, 2);
aoqi@1 639
aoqi@1 640 __ b(Loop);
aoqi@1 641 __ delayed()->addi(A4, A4, -1);
aoqi@1 642
aoqi@1 643 __ bind(haveResult);
aoqi@1 644 __ dsubu(V0, A5, A6);
aoqi@1 645
aoqi@1 646 __ bind(LoopEnd);
aoqi@1 647 #endif
aoqi@1 648 return_op(FrameMap::_v0_opr);
aoqi@1 649 }
aoqi@1 650
aoqi@1 651
aoqi@1 652 void LIR_Assembler::return_op(LIR_Opr result) {
aoqi@1 653 assert(result->is_illegal() || !result->is_single_cpu() || result->as_register() == V0, "word returns are in V0");
aoqi@1 654 // Pop the stack before the safepoint code
aoqi@1 655 __ leave();
aoqi@1 656 #ifndef _LP64
aoqi@1 657 //by aoqi
aoqi@1 658 __ lui(AT, Assembler::split_high((intptr_t)os::get_polling_page()
aoqi@1 659 + (SafepointPollOffset % os::vm_page_size())));
aoqi@1 660 __ relocate(relocInfo::poll_return_type);
aoqi@1 661 __ lw(AT, AT, Assembler::split_low((intptr_t)os::get_polling_page()
aoqi@1 662 + (SafepointPollOffset % os::vm_page_size())));
aoqi@1 663 #else
aoqi@1 664 #ifndef OPT_SAFEPOINT
aoqi@1 665 // do not know how to handle relocate yet. do not know li or li64 should be used neither. by aoqi. 20111207 FIXME.
aoqi@1 666 __ li48(AT, (intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()));
aoqi@1 667 __ relocate(relocInfo::poll_return_type);
aoqi@1 668 __ lw(AT, AT, 0);
aoqi@1 669 #else
aoqi@1 670 __ lui(AT, Assembler::split_high((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())));
aoqi@1 671 __ relocate(relocInfo::poll_return_type);
aoqi@1 672 __ lw(AT, AT, Assembler::split_low((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())));
aoqi@1 673 #endif
aoqi@1 674 #endif
aoqi@1 675
aoqi@1 676 __ jr(RA);
aoqi@1 677 __ delayed()->nop();
aoqi@1 678 }
aoqi@1 679
aoqi@1 680 //read protect mem to R0 won't cause the exception only in godson-2e, So I modify R0 to AT .@jerome,11/25,2006
aoqi@1 681 int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
aoqi@1 682 assert(info != NULL, "info must not be null for safepoint poll");
aoqi@1 683 int offset = __ offset();
aoqi@1 684 Register r = tmp->as_register();
aoqi@1 685 #ifndef _LP64
aoqi@1 686 //by aoqi
aoqi@1 687 __ lui(r, Assembler::split_high((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())));
aoqi@1 688 add_debug_info_for_branch(info);
aoqi@1 689 __ relocate(relocInfo::poll_type);
aoqi@1 690 __ lw(AT, r, Assembler::split_low((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())));
aoqi@1 691 #else
aoqi@1 692 #ifndef OPT_SAFEPOINT
aoqi@1 693 // do not know how to handle relocate yet. do not know li or li64 should be used neither. by aoqi. 20111207 FIXME.
aoqi@1 694 //__ lui(r, Assembler::split_high((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())));
aoqi@1 695 __ li48(r, (intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()));
aoqi@1 696 add_debug_info_for_branch(info);
aoqi@1 697 __ relocate(relocInfo::poll_type);
aoqi@1 698 //__ lw(AT, r, Assembler::split_low((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())));
aoqi@1 699 __ lw(AT, r, 0);
aoqi@1 700 #else
aoqi@1 701 __ lui(r, Assembler::split_high((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())));
aoqi@1 702 add_debug_info_for_branch(info);
aoqi@1 703 __ relocate(relocInfo::poll_type);
aoqi@1 704 __ lw(AT, r, Assembler::split_low((intptr_t)os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())));
aoqi@1 705 #endif
aoqi@1 706 #endif
aoqi@1 707 return offset;
aoqi@1 708 }
aoqi@1 709
aoqi@1 710 void LIR_Assembler::move_regs(Register from_reg, Register to_reg) {
aoqi@1 711 if (from_reg != to_reg) __ move(to_reg, from_reg);
aoqi@1 712 }
aoqi@1 713
aoqi@1 714
aoqi@1 715 void LIR_Assembler::swap_reg(Register a, Register b) {
aoqi@1 716 __ xorr(a, a, b);
aoqi@1 717 __ xorr(b, a, b);
aoqi@1 718 __ xorr(a, a, b);
aoqi@1 719 }
aoqi@1 720
aoqi@1 721 void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
aoqi@1 722 assert(src->is_constant(), "should not call otherwise");
aoqi@1 723 assert(dest->is_register(), "should not call otherwise");
aoqi@1 724 LIR_Const* c = src->as_constant_ptr();
aoqi@1 725 switch (c->type()) {
aoqi@1 726 case T_INT:
aoqi@1 727 {
aoqi@1 728 jint con = c->as_jint();
aoqi@1 729 if (dest->is_single_cpu()) {
aoqi@1 730 assert(patch_code == lir_patch_none, "no patching handled here");
aoqi@1 731 __ move(dest->as_register(), con);
aoqi@1 732 } else {
aoqi@1 733 assert(dest->is_single_fpu(), "wrong register kind");
aoqi@1 734 __ move(AT, con);
aoqi@1 735 __ mtc1(AT, dest->as_float_reg());
aoqi@1 736 }
aoqi@1 737 }
aoqi@1 738 break;
aoqi@1 739
aoqi@1 740 case T_LONG:
aoqi@1 741 {
aoqi@1 742 #ifndef _LP64
aoqi@1 743 jlong con = c->as_jlong();
aoqi@1 744 jint* conhi = (jint*)&con + 1;
aoqi@1 745 jint* conlow = (jint*)&con;
aoqi@1 746
aoqi@1 747 if (dest->is_double_cpu()) {
aoqi@1 748 __ move(dest->as_register_lo(), *conlow);
aoqi@1 749 __ move(dest->as_register_hi(), *conhi);
aoqi@1 750 } else {
aoqi@1 751 // assert(dest->is_double(), "wrong register kind");
aoqi@1 752 __ move(AT, *conlow);
aoqi@1 753 __ mtc1(AT, dest->as_double_reg());
aoqi@1 754 __ move(AT, *conhi);
aoqi@1 755 __ mtc1(AT, dest->as_double_reg()+1);
aoqi@1 756 }
aoqi@1 757 #else
aoqi@1 758 if (dest->is_double_cpu()) {
aoqi@1 759 __ li(dest->as_register_lo(), c->as_jlong());
aoqi@1 760 } else {
aoqi@1 761 __ li(dest->as_register(), c->as_jlong());
aoqi@1 762 }
aoqi@1 763 #endif
aoqi@1 764 }
aoqi@1 765 break;
aoqi@1 766
aoqi@1 767 case T_OBJECT:
aoqi@1 768 {
aoqi@1 769 if (patch_code == lir_patch_none) {
aoqi@1 770 jobject2reg(c->as_jobject(), dest->as_register());
aoqi@1 771 } else {
aoqi@1 772 jobject2reg_with_patching(dest->as_register(), info);
aoqi@1 773 }
aoqi@1 774 }
aoqi@1 775 break;
aoqi@1 776
aoqi@1 777 case T_FLOAT:
aoqi@1 778 {
aoqi@1 779 address const_addr = float_constant(c->as_jfloat());
aoqi@1 780 assert (const_addr != NULL, "must create float constant in the constant table");
aoqi@1 781
aoqi@1 782 if (dest->is_single_fpu()) {
aoqi@1 783 __ relocate(relocInfo::internal_pc_type);
aoqi@1 784 #ifndef _LP64
aoqi@1 785 //by_css
aoqi@1 786 __ lui(AT, Assembler::split_high((int)const_addr));
aoqi@1 787 __ addiu(AT, AT, Assembler::split_low((int)const_addr));
aoqi@1 788 #else
aoqi@1 789 __ li48(AT, (long)const_addr);
aoqi@1 790 #endif
aoqi@1 791 __ lwc1(dest->as_float_reg(), AT, 0);
aoqi@1 792
aoqi@1 793 } else {
aoqi@1 794 assert(dest->is_single_cpu(), "Must be a cpu register.");
aoqi@1 795 assert(dest->as_register() != AT, "AT can not be allocated.");
aoqi@1 796
aoqi@1 797 __ relocate(relocInfo::internal_pc_type);
aoqi@1 798 #ifndef _LP64
aoqi@1 799 //by_css
aoqi@1 800 __ lui(AT, Assembler::split_high((int)const_addr));
aoqi@1 801 __ addiu(AT, AT, Assembler::split_low((int)const_addr));
aoqi@1 802 #else
aoqi@1 803 __ li48(AT, (long)const_addr);
aoqi@1 804 #endif
aoqi@1 805 __ lw(dest->as_register(), AT, 0);
aoqi@1 806 }
aoqi@1 807 }
aoqi@1 808 break;
aoqi@1 809
aoqi@1 810 case T_DOUBLE:
aoqi@1 811 {
aoqi@1 812 address const_addr = double_constant(c->as_jdouble());
aoqi@1 813 assert (const_addr != NULL, "must create double constant in the constant table");
aoqi@1 814
aoqi@1 815 if (dest->is_double_fpu()) {
aoqi@1 816 __ relocate(relocInfo::internal_pc_type);
aoqi@1 817 #ifndef _LP64
aoqi@1 818 //by_css
aoqi@1 819 __ lui(AT, Assembler::split_high((int)const_addr));
aoqi@1 820 __ addiu(AT, AT, Assembler::split_low((int)const_addr));
aoqi@1 821 __ lwc1(dest->as_double_reg(), AT, 0);
aoqi@1 822 __ lwc1(dest->as_double_reg()+1, AT, 4);
aoqi@1 823 #else
aoqi@1 824 __ li48(AT, (long)const_addr);
aoqi@1 825 __ ldc1(dest->as_double_reg(), AT, 0);
aoqi@1 826 #endif
aoqi@1 827 } else {
aoqi@1 828 assert(dest->as_register_lo() != AT, "AT can not be allocated.");
aoqi@1 829 assert(dest->as_register_hi() != AT, "AT can not be allocated.");
aoqi@1 830
aoqi@1 831 __ relocate(relocInfo::internal_pc_type);
aoqi@1 832 #ifndef _LP64
aoqi@1 833 //by_css
aoqi@1 834 __ lui(AT, Assembler::split_high((int)const_addr));
aoqi@1 835 __ addiu(AT, AT, Assembler::split_low((int)const_addr));
aoqi@1 836 __ lw(dest->as_register_lo(), AT, 0);
aoqi@1 837 __ lw(dest->as_register_hi(), AT, 4);
aoqi@1 838 #else
aoqi@1 839 __ li48(AT, (long)const_addr);
aoqi@1 840 __ ld(dest->as_register_lo(), AT, 0);
aoqi@1 841 #endif
aoqi@1 842 }
aoqi@1 843 }
aoqi@1 844 break;
aoqi@1 845
aoqi@1 846 default:
aoqi@1 847 ShouldNotReachHere();
aoqi@1 848 }
aoqi@1 849 }
aoqi@1 850
aoqi@1 851
aoqi@1 852 void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) {
aoqi@1 853 assert(src->is_constant(), "should not call otherwise");
aoqi@1 854 assert(dest->is_stack(), "should not call otherwise");
aoqi@1 855 LIR_Const* c = src->as_constant_ptr();
aoqi@1 856 switch (c->type()) {
aoqi@1 857 case T_INT: // fall through
aoqi@1 858 case T_FLOAT:
aoqi@1 859 __ move(AT, c->as_jint_bits());
aoqi@1 860 __ sw(AT, frame_map()->address_for_slot(dest->single_stack_ix()));
aoqi@1 861 break;
aoqi@1 862
aoqi@1 863 case T_OBJECT:
aoqi@1 864 if (c->as_jobject() == NULL) {
aoqi@1 865 __ st_ptr(R0, frame_map()->address_for_slot(dest->single_stack_ix()));
aoqi@1 866 } else {
aoqi@1 867 int oop_index = __ oop_recorder()->find_index(c->as_jobject());
aoqi@1 868 RelocationHolder rspec = oop_Relocation::spec(oop_index);
aoqi@1 869 __ relocate(rspec);
aoqi@1 870 #ifndef _LP64
aoqi@1 871 //by_css
aoqi@1 872 __ lui(AT, Assembler::split_high((int)c->as_jobject()));
aoqi@1 873 __ addiu(AT, AT, Assembler::split_low((int)c->as_jobject()));
aoqi@1 874 #else
aoqi@1 875 __ li48(AT, (long)c->as_jobject());
aoqi@1 876 #endif
aoqi@1 877 __ st_ptr(AT, frame_map()->address_for_slot(dest->single_stack_ix()));
aoqi@1 878 }
aoqi@1 879 break;
aoqi@1 880 case T_LONG: // fall through
aoqi@1 881 case T_DOUBLE:
aoqi@1 882 #ifndef _LP64
aoqi@1 883 __ move(AT, c->as_jint_lo_bits());
aoqi@1 884 __ sw(AT, frame_map()->address_for_slot(dest->double_stack_ix(),
aoqi@1 885 lo_word_offset_in_bytes));
aoqi@1 886 __ move(AT, c->as_jint_hi_bits());
aoqi@1 887 __ sw(AT, frame_map()->address_for_slot(dest->double_stack_ix(),
aoqi@1 888 hi_word_offset_in_bytes));
aoqi@1 889 #else
aoqi@1 890 __ move(AT, c->as_jlong_bits());
aoqi@1 891 __ sd(AT, frame_map()->address_for_slot(dest->double_stack_ix(),
aoqi@1 892 lo_word_offset_in_bytes));
aoqi@1 893 #endif
aoqi@1 894 break;
aoqi@1 895 default:
aoqi@1 896 ShouldNotReachHere();
aoqi@1 897 }
aoqi@1 898 }
aoqi@1 899
aoqi@1 900 void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) {
aoqi@1 901 assert(src->is_constant(), "should not call otherwise");
aoqi@1 902 assert(dest->is_address(), "should not call otherwise");
aoqi@1 903 LIR_Const* c = src->as_constant_ptr();
aoqi@1 904 LIR_Address* addr = dest->as_address_ptr();
aoqi@1 905
aoqi@1 906 int null_check_here = code_offset();
aoqi@1 907 switch (type) {
aoqi@1 908 case T_LONG: // fall through
aoqi@1 909 case T_DOUBLE:
aoqi@1 910 #ifndef _LP64
aoqi@1 911 __ move(AT, c->as_jint_hi_bits());
aoqi@1 912 __ sw(AT, as_Address_hi(addr));
aoqi@1 913 __ move(AT, c->as_jint_lo_bits());
aoqi@1 914 __ sw(AT, as_Address_lo(addr));
aoqi@1 915 #else
aoqi@1 916 if(c->as_jlong_bits() != 0)
aoqi@1 917 {
aoqi@1 918 /* DoublePrint: -0.0
aoqi@1 919 * (gdb) print /x -9223372036854775808
aoqi@1 920 * $1 = 0x8000000000000000
aoqi@1 921 */
aoqi@1 922 __ li64(AT, c->as_jlong_bits());
aoqi@1 923 __ sd(AT, as_Address_lo(addr));
aoqi@1 924 }
aoqi@1 925 else
aoqi@1 926 __ sd(R0, as_Address(addr));
aoqi@1 927 #endif
aoqi@1 928 break;
aoqi@1 929 case T_OBJECT: // fall through
aoqi@1 930 case T_ARRAY:
aoqi@1 931 if (c->as_jobject() == NULL){
aoqi@1 932 if (UseCompressedOops && !wide) {
aoqi@1 933 __ sw(R0, as_Address(addr));
aoqi@1 934 } else {
aoqi@1 935 __ st_ptr(R0, as_Address(addr));
aoqi@1 936 }
aoqi@1 937 } else {
aoqi@1 938 int oop_index = __ oop_recorder()->find_index(c->as_jobject());
aoqi@1 939 RelocationHolder rspec = oop_Relocation::spec(oop_index);
aoqi@1 940 __ relocate(rspec);
aoqi@1 941 #ifndef _LP64
aoqi@1 942 __ lui(AT, Assembler::split_high((int)c->as_jobject()));
aoqi@1 943 __ addiu(AT, AT, Assembler::split_low((int)c->as_jobject()));
aoqi@1 944 __ st_ptr(AT, as_Address(addr));
aoqi@1 945 null_check_here = code_offset();
aoqi@1 946 #else
aoqi@1 947 //by_css
aoqi@1 948 __ li64(AT, (long)c->as_jobject());
aoqi@1 949 if (UseCompressedOops && !wide) {
aoqi@1 950 __ encode_heap_oop(AT);
aoqi@1 951 null_check_here = code_offset();
aoqi@1 952 __ sw(AT, as_Address(addr));
aoqi@1 953 } else {
aoqi@1 954 __ st_ptr(AT, as_Address(addr));
aoqi@1 955 }
aoqi@1 956 #endif
aoqi@1 957 }
aoqi@1 958 break;
aoqi@1 959 case T_INT: // fall through
aoqi@1 960 case T_FLOAT:
aoqi@1 961 if(c->as_jint_bits() != 0)
aoqi@1 962 {
aoqi@1 963 __ move(AT, c->as_jint_bits());
aoqi@1 964 __ sw(AT, as_Address(addr));
aoqi@1 965 }
aoqi@1 966 else
aoqi@1 967 __ sw(R0, as_Address(addr));
aoqi@1 968 break;
aoqi@1 969 case T_BOOLEAN: // fall through
aoqi@1 970 case T_BYTE:
aoqi@1 971 if(c->as_jint() != 0)
aoqi@1 972 {
aoqi@1 973 __ move(AT, c->as_jint());
aoqi@1 974 __ sb(AT, as_Address(addr));
aoqi@1 975 }
aoqi@1 976 else
aoqi@1 977 __ sb(R0, as_Address(addr));
aoqi@1 978 break;
aoqi@1 979 case T_CHAR: // fall through
aoqi@1 980 case T_SHORT:
aoqi@1 981 if(c->as_jint() != 0)
aoqi@1 982 {
aoqi@1 983 __ move(AT, c->as_jint());
aoqi@1 984 __ sh(AT, as_Address(addr));
aoqi@1 985 }
aoqi@1 986 else
aoqi@1 987 __ sh(R0, as_Address(addr));
aoqi@1 988 break;
aoqi@1 989 default: ShouldNotReachHere();
aoqi@1 990 };
aoqi@1 991 if (info != NULL) add_debug_info_for_null_check(null_check_here, info);
aoqi@1 992 }
aoqi@1 993
aoqi@1 994 void LIR_Assembler::reg2reg(LIR_Opr src, LIR_Opr dest) {
aoqi@1 995 assert(src->is_register(), "should not call otherwise");
aoqi@1 996 assert(dest->is_register(), "should not call otherwise");
aoqi@1 997 if (dest->is_float_kind() && src->is_float_kind()) {
aoqi@1 998 // float to float moves
aoqi@1 999 if (dest->is_single_fpu()) {
aoqi@1 1000 assert(src->is_single_fpu(), "must both be float");
aoqi@1 1001 __ mov_s(dest->as_float_reg(), src->as_float_reg());
aoqi@1 1002 } else {
aoqi@1 1003 assert(src->is_double_fpu(), "must bothe be double");
aoqi@1 1004 __ mov_d( dest->as_double_reg(),src->as_double_reg());
aoqi@1 1005 }
aoqi@1 1006 } else if (!dest->is_float_kind() && !src->is_float_kind()) {
aoqi@1 1007 // int to int moves
aoqi@1 1008 if (dest->is_single_cpu()) {
aoqi@1 1009 #ifdef _LP64
aoqi@1 1010 //FIXME aoqi: copy from x86
aoqi@1 1011 if (src->type() == T_LONG) {
aoqi@1 1012 // Can do LONG -> OBJECT
aoqi@1 1013 move_regs(src->as_register_lo(), dest->as_register());
aoqi@1 1014 return;
aoqi@1 1015 }
aoqi@1 1016 #endif
aoqi@1 1017 assert(src->is_single_cpu(), "must match");
aoqi@1 1018 if (dest->type() == T_INT) {
aoqi@1 1019 __ move_u32(dest->as_register(), src->as_register());
aoqi@1 1020 }
aoqi@1 1021 else
aoqi@1 1022 move_regs(src->as_register(), dest->as_register());
aoqi@1 1023 } else if (dest->is_double_cpu()) {
aoqi@1 1024 #ifdef _LP64
aoqi@1 1025 if (src->type() == T_OBJECT || src->type() == T_ARRAY) {
aoqi@1 1026 // Surprising to me but we can see move of a long to t_object
aoqi@1 1027 __ verify_oop(src->as_register());
aoqi@1 1028 move_regs(src->as_register(), dest->as_register_lo());
aoqi@1 1029 return;
aoqi@1 1030 }
aoqi@1 1031 #endif
aoqi@1 1032 Register f_lo;
aoqi@1 1033 Register f_hi;
aoqi@1 1034 Register t_lo;
aoqi@1 1035 Register t_hi;
aoqi@1 1036
aoqi@1 1037 if (src->is_single_cpu())
aoqi@1 1038 {
aoqi@1 1039 f_lo = src->as_register();
aoqi@1 1040 t_lo = dest->as_register_lo();
aoqi@1 1041 }
aoqi@1 1042 else
aoqi@1 1043 {
aoqi@1 1044 f_lo = src->as_register_lo();
aoqi@1 1045 f_hi = src->as_register_hi();
aoqi@1 1046 t_lo = dest->as_register_lo();
aoqi@1 1047 t_hi = dest->as_register_hi();
aoqi@1 1048 assert(f_hi == f_lo, "must be same");
aoqi@1 1049 assert(t_hi == t_lo, "must be same");
aoqi@1 1050 }
aoqi@1 1051 #ifdef _LP64
aoqi@1 1052 move_regs(f_lo, t_lo);
aoqi@1 1053 #else
aoqi@1 1054 /*
aoqi@1 1055 if (src->as_register_hi() != dest->as_register_lo()) {
aoqi@1 1056 move_regs(src->as_register_lo(), dest->as_register_lo());
aoqi@1 1057 move_regs(src->as_register_hi(), dest->as_register_hi());
aoqi@1 1058 } else if (src->as_register_lo() != dest->as_register_hi()) {
aoqi@1 1059 move_regs(src->as_register_hi(), dest->as_register_hi());
aoqi@1 1060 move_regs(src->as_register_lo(), dest->as_register_lo());
aoqi@1 1061 } else {
aoqi@1 1062 swap_reg(src->as_register_lo(), src->as_register_hi());
aoqi@1 1063 }
aoqi@1 1064 */
aoqi@1 1065 assert(f_lo != f_hi && t_lo != t_hi, "invalid register allocation");
aoqi@1 1066
aoqi@1 1067 if (f_lo == t_hi && f_hi == t_lo) {
aoqi@1 1068 swap_reg(f_lo, f_hi);
aoqi@1 1069 } else if (f_hi == t_lo) {
aoqi@1 1070 assert(f_lo != t_hi, "overwriting register");
aoqi@1 1071 move_regs(f_hi, t_hi);
aoqi@1 1072 move_regs(f_lo, t_lo);
aoqi@1 1073 } else {
aoqi@1 1074 assert(f_hi != t_lo, "overwriting register");
aoqi@1 1075 move_regs(f_lo, t_lo);
aoqi@1 1076 move_regs(f_hi, t_hi);
aoqi@1 1077 }
aoqi@1 1078 #endif // LP64
aoqi@1 1079 }
aoqi@1 1080 } else {
aoqi@1 1081 // float to int or int to float moves
aoqi@1 1082 if (dest->is_double_cpu()) {
aoqi@1 1083 assert(src->is_double_fpu(), "must match");
aoqi@1 1084 __ mfc1(dest->as_register_lo(), src->as_double_reg());
aoqi@1 1085 #ifndef _LP64
aoqi@1 1086 __ mfc1(dest->as_register_hi(), src->as_double_reg() + 1);
aoqi@1 1087 #endif
aoqi@1 1088 } else if (dest->is_single_cpu()) {
aoqi@1 1089 assert(src->is_single_fpu(), "must match");
aoqi@1 1090 __ mfc1(dest->as_register(), src->as_float_reg());
aoqi@1 1091 } else if (dest->is_double_fpu()) {
aoqi@1 1092 assert(src->is_double_cpu(), "must match");
aoqi@1 1093 __ mtc1(src->as_register_lo(), dest->as_double_reg());
aoqi@1 1094 #ifndef _LP64
aoqi@1 1095 __ mtc1(src->as_register_hi(), dest->as_double_reg() + 1);
aoqi@1 1096 #endif
aoqi@1 1097 } else if (dest->is_single_fpu()) {
aoqi@1 1098 assert(src->is_single_cpu(), "must match");
aoqi@1 1099 __ mtc1(src->as_register(), dest->as_float_reg());
aoqi@1 1100 }
aoqi@1 1101 }
aoqi@1 1102 }
aoqi@1 1103
aoqi@1 1104
aoqi@1 1105 void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type,bool pop_fpu_stack) {
aoqi@1 1106 assert(src->is_register(), "should not call otherwise");
aoqi@1 1107 assert(dest->is_stack(), "should not call otherwise");
aoqi@1 1108
aoqi@1 1109 if (src->is_single_cpu()) {
aoqi@1 1110 Address dst = frame_map()->address_for_slot(dest->single_stack_ix());
aoqi@1 1111 if (type == T_OBJECT || type == T_ARRAY) {
aoqi@1 1112 __ verify_oop(src->as_register());
aoqi@1 1113 }
aoqi@1 1114 #ifdef _LP64
aoqi@1 1115 if (type == T_INT)
aoqi@1 1116 __ sw(src->as_register(),dst);
aoqi@1 1117 else
aoqi@1 1118 #endif
aoqi@1 1119 __ st_ptr(src->as_register(),dst);
aoqi@1 1120 } else if (src->is_double_cpu()) {
aoqi@1 1121 Address dstLO = frame_map()->address_for_slot(dest->double_stack_ix(), lo_word_offset_in_bytes);
aoqi@1 1122 Address dstHI = frame_map()->address_for_slot(dest->double_stack_ix(), hi_word_offset_in_bytes);
aoqi@1 1123 __ st_ptr(src->as_register_lo(),dstLO);
aoqi@1 1124 NOT_LP64(__ st_ptr(src->as_register_hi(),dstHI));
aoqi@1 1125 }else if (src->is_single_fpu()) {
aoqi@1 1126 Address dst_addr = frame_map()->address_for_slot(dest->single_stack_ix());
aoqi@1 1127 __ swc1(src->as_float_reg(), dst_addr);
aoqi@1 1128
aoqi@1 1129 } else if (src->is_double_fpu()) {
aoqi@1 1130 Address dst_addr = frame_map()->address_for_slot(dest->double_stack_ix());
aoqi@1 1131 #ifndef _LP64
aoqi@1 1132 __ swc1(src->as_double_reg(), dst_addr);
aoqi@1 1133 __ swc1(src->as_double_reg() + 1, dst_addr.base(), dst_addr.disp() + 4);
aoqi@1 1134 #else
aoqi@1 1135 __ sdc1(src->as_double_reg(), dst_addr);
aoqi@1 1136 #endif
aoqi@1 1137
aoqi@1 1138 } else {
aoqi@1 1139 ShouldNotReachHere();
aoqi@1 1140 }
aoqi@1 1141 }
aoqi@1 1142
aoqi@1 1143 //FIXME
aoqi@1 1144 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*/) {
aoqi@1 1145 LIR_Address* to_addr = dest->as_address_ptr();
aoqi@1 1146 //Register dest_reg = to_addr->base()->as_register();
aoqi@1 1147 // FIXME aoqi
aoqi@1 1148 Register dest_reg = to_addr->base()->is_single_cpu()? to_addr->base()->as_register() : to_addr->base()->as_register_lo();
aoqi@1 1149 PatchingStub* patch = NULL;
aoqi@1 1150 bool needs_patching = (patch_code != lir_patch_none);
aoqi@1 1151 Register disp_reg = NOREG;
aoqi@1 1152 int disp_value = to_addr->disp();
aoqi@1 1153 /*
aoqi@1 1154 the start position of patch template is labeled by "new PatchingStub(...)"
aoqi@1 1155 during patch, T9 will be changed and not restore
aoqi@1 1156 that's why we use S7 but not T9 as compressed_src here
aoqi@1 1157 */
aoqi@1 1158 Register compressed_src = S7;
aoqi@1 1159
aoqi@1 1160 if (type == T_ARRAY || type == T_OBJECT) {
aoqi@1 1161 __ verify_oop(src->as_register());
aoqi@1 1162 #ifdef _LP64
aoqi@1 1163 if (UseCompressedOops && !wide) {
aoqi@1 1164 __ move(compressed_src, src->as_register());
aoqi@1 1165 __ encode_heap_oop(compressed_src);
aoqi@1 1166 }
aoqi@1 1167 #endif
aoqi@1 1168 }
aoqi@1 1169
aoqi@1 1170 if (needs_patching) {
aoqi@1 1171 patch = new PatchingStub(_masm, PatchingStub::access_field_id);
aoqi@1 1172 assert(!src->is_double_cpu() ||
aoqi@1 1173 patch_code == lir_patch_none ||
aoqi@1 1174 patch_code == lir_patch_normal,
aoqi@1 1175 "patching doesn't match register");
aoqi@1 1176 Address toa = as_Address(to_addr);
aoqi@1 1177 assert(toa.disp() != 0, "must have");
aoqi@1 1178 }
aoqi@1 1179
aoqi@1 1180 if (info != NULL) {
aoqi@1 1181 add_debug_info_for_null_check_here(info);
aoqi@1 1182 }
aoqi@1 1183 if (needs_patching) {
aoqi@1 1184 disp_reg = AT;
aoqi@1 1185 __ lui(AT, Assembler::split_high(disp_value));
aoqi@1 1186 __ addiu(AT, AT, Assembler::split_low(disp_value));
aoqi@1 1187 } else if (!Assembler::is_simm16(disp_value)) {
aoqi@1 1188 disp_reg = AT;
aoqi@1 1189 __ lui(AT, Assembler::split_high(disp_value));
aoqi@1 1190 }
aoqi@1 1191 int offset = code_offset();
aoqi@1 1192
aoqi@1 1193 switch(type) {
aoqi@1 1194 case T_DOUBLE:
aoqi@1 1195 assert(src->is_double_fpu(), "just check");
aoqi@1 1196 if (disp_reg == noreg) {
aoqi@1 1197 #ifndef _LP64
aoqi@1 1198 __ swc1(src->as_double_reg(), dest_reg, disp_value);
aoqi@1 1199 __ swc1(src->as_double_reg()+1, dest_reg, disp_value+4);
aoqi@1 1200 #else
aoqi@1 1201 __ sdc1(src->as_double_reg(), dest_reg, disp_value);
aoqi@1 1202 #endif
aoqi@1 1203 } else if (needs_patching) {
aoqi@1 1204 __ add(AT, dest_reg, disp_reg);
aoqi@1 1205 #ifndef _LP64
aoqi@1 1206 __ swc1(src->as_double_reg(), AT, 0);
aoqi@1 1207 __ swc1(src->as_double_reg()+1, AT, 4);
aoqi@1 1208 #else
aoqi@1 1209 __ sdc1(src->as_double_reg(), AT, 0);
aoqi@1 1210 #endif
aoqi@1 1211 } else {
aoqi@1 1212 __ add(AT, dest_reg, disp_reg);
aoqi@1 1213 #ifndef _LP64
aoqi@1 1214 __ swc1(src->as_double_reg(), AT, Assembler::split_low(disp_value));
aoqi@1 1215 __ swc1(src->as_double_reg()+1, AT, Assembler::split_low(disp_value) + 4);
aoqi@1 1216 #else
aoqi@1 1217 __ sdc1(src->as_double_reg(), AT, Assembler::split_low(disp_value));
aoqi@1 1218 #endif
aoqi@1 1219 }
aoqi@1 1220 break;
aoqi@1 1221
aoqi@1 1222 case T_FLOAT:
aoqi@1 1223 if (disp_reg == noreg) {
aoqi@1 1224 __ swc1(src->as_float_reg(), dest_reg, disp_value);
aoqi@1 1225 } else if(needs_patching) {
aoqi@1 1226 __ add(AT, dest_reg, disp_reg);
aoqi@1 1227 __ swc1(src->as_float_reg(), AT, 0);
aoqi@1 1228 } else {
aoqi@1 1229 __ add(AT, dest_reg, disp_reg);
aoqi@1 1230 __ swc1(src->as_float_reg(), AT, Assembler::split_low(disp_value));
aoqi@1 1231 }
aoqi@1 1232 break;
aoqi@1 1233
aoqi@1 1234 case T_LONG: {
aoqi@1 1235 Register from_lo = src->as_register_lo();
aoqi@1 1236 Register from_hi = src->as_register_hi();
aoqi@1 1237 #ifdef _LP64
aoqi@1 1238 if (needs_patching) {
aoqi@1 1239 __ add(AT, dest_reg, disp_reg);
aoqi@1 1240 __ st_ptr(from_lo, AT, 0);
aoqi@1 1241 } else {
aoqi@1 1242 __ st_ptr(from_lo, as_Address_lo(to_addr));
aoqi@1 1243 }
aoqi@1 1244 #else
aoqi@1 1245 Register base = to_addr->base()->as_register();
aoqi@1 1246 Register index = noreg;
aoqi@1 1247 if (to_addr->index()->is_register()) {
aoqi@1 1248 index = to_addr->index()->as_register();
aoqi@1 1249 }
aoqi@1 1250 if (base == from_lo || index == from_lo) {
aoqi@1 1251 assert(base != from_hi, "can't be");
aoqi@1 1252 assert(index == noreg || (index != base && index != from_hi), "can't handle this");
aoqi@1 1253 if (needs_patching) {
aoqi@1 1254 __ add(AT, dest_reg, disp_reg);
aoqi@1 1255 NOT_LP64(__ st_ptr(from_hi, AT, longSize/2);)
aoqi@1 1256 __ st_ptr(from_lo, AT, 0);
aoqi@1 1257 } else {
aoqi@1 1258 __ st_ptr(from_hi, as_Address_hi(to_addr));
aoqi@1 1259 __ st_ptr(from_lo, as_Address_lo(to_addr));
aoqi@1 1260 }
aoqi@1 1261 } else {
aoqi@1 1262 assert(index == noreg || (index != base && index != from_lo), "can't handle this");
aoqi@1 1263 if (needs_patching) {
aoqi@1 1264 __ add(AT, dest_reg, disp_reg);
aoqi@1 1265 __ st_ptr(from_lo, AT, 0);
aoqi@1 1266 __ st_ptr(from_hi, AT, longSize/2);
aoqi@1 1267 } else {
aoqi@1 1268 __ st_ptr(from_lo, as_Address_lo(to_addr));
aoqi@1 1269 __ st_ptr(from_hi, as_Address_hi(to_addr));
aoqi@1 1270 }
aoqi@1 1271 }
aoqi@1 1272 #endif
aoqi@1 1273 break;
aoqi@1 1274 }
aoqi@1 1275 case T_ARRAY:
aoqi@1 1276 case T_OBJECT:
aoqi@1 1277 #ifdef _LP64
aoqi@1 1278 if (UseCompressedOops && !wide) {
aoqi@1 1279 if (disp_reg == noreg) {
aoqi@1 1280 __ sw(compressed_src, dest_reg, disp_value);
aoqi@1 1281 } else if (needs_patching) {
aoqi@1 1282 __ add(AT, dest_reg, disp_reg);
aoqi@1 1283 __ sw(compressed_src, AT, 0);
aoqi@1 1284 } else {
aoqi@1 1285 __ add(AT, dest_reg, disp_reg);
aoqi@1 1286 __ sw(compressed_src, AT, Assembler::split_low(disp_value));
aoqi@1 1287 }
aoqi@1 1288 } else {
aoqi@1 1289 if (disp_reg == noreg) {
aoqi@1 1290 __ st_ptr(src->as_register(), dest_reg, disp_value);
aoqi@1 1291 } else if (needs_patching) {
aoqi@1 1292 __ add(AT, dest_reg, disp_reg);
aoqi@1 1293 __ st_ptr(src->as_register(), AT, 0);
aoqi@1 1294 } else {
aoqi@1 1295 __ add(AT, dest_reg, disp_reg);
aoqi@1 1296 __ st_ptr(src->as_register(), AT, Assembler::split_low(disp_value));
aoqi@1 1297 }
aoqi@1 1298 }
aoqi@1 1299 break;
aoqi@1 1300 #endif
aoqi@1 1301 case T_ADDRESS:
aoqi@1 1302 #ifdef _LP64
aoqi@1 1303 if (disp_reg == noreg) {
aoqi@1 1304 __ st_ptr(src->as_register(), dest_reg, disp_value);
aoqi@1 1305 } else if (needs_patching) {
aoqi@1 1306 __ add(AT, dest_reg, disp_reg);
aoqi@1 1307 __ st_ptr(src->as_register(), AT, 0);
aoqi@1 1308 } else {
aoqi@1 1309 __ add(AT, dest_reg, disp_reg);
aoqi@1 1310 __ st_ptr(src->as_register(), AT, Assembler::split_low(disp_value));
aoqi@1 1311 }
aoqi@1 1312 break;
aoqi@1 1313 #endif
aoqi@1 1314 case T_INT:
aoqi@1 1315 if (disp_reg == noreg) {
aoqi@1 1316 __ sw(src->as_register(), dest_reg, disp_value);
aoqi@1 1317 } else if (needs_patching) {
aoqi@1 1318 __ add(AT, dest_reg, disp_reg);
aoqi@1 1319 __ sw(src->as_register(), AT, 0);
aoqi@1 1320 } else {
aoqi@1 1321 __ add(AT, dest_reg, disp_reg);
aoqi@1 1322 __ sw(src->as_register(), AT, Assembler::split_low(disp_value));
aoqi@1 1323 }
aoqi@1 1324 break;
aoqi@1 1325
aoqi@1 1326 case T_CHAR:
aoqi@1 1327 case T_SHORT:
aoqi@1 1328 if (disp_reg == noreg) {
aoqi@1 1329 __ sh(src->as_register(), dest_reg, disp_value);
aoqi@1 1330 } else if (needs_patching) {
aoqi@1 1331 __ add(AT, dest_reg, disp_reg);
aoqi@1 1332 __ sh(src->as_register(), AT, 0);
aoqi@1 1333 } else {
aoqi@1 1334 __ add(AT, dest_reg, disp_reg);
aoqi@1 1335 __ sh(src->as_register(), AT, Assembler::split_low(disp_value));
aoqi@1 1336 }
aoqi@1 1337 break;
aoqi@1 1338
aoqi@1 1339 case T_BYTE:
aoqi@1 1340 case T_BOOLEAN:
aoqi@1 1341 assert(src->is_single_cpu(), "just check");
aoqi@1 1342
aoqi@1 1343 if (disp_reg == noreg) {
aoqi@1 1344 __ sb(src->as_register(), dest_reg, disp_value);
aoqi@1 1345 } else if (needs_patching) {
aoqi@1 1346 __ add(AT, dest_reg, disp_reg);
aoqi@1 1347 __ sb(src->as_register(), AT, 0);
aoqi@1 1348 } else {
aoqi@1 1349 __ add(AT, dest_reg, disp_reg);
aoqi@1 1350 __ sb(src->as_register(), AT, Assembler::split_low(disp_value));
aoqi@1 1351 }
aoqi@1 1352 break;
aoqi@1 1353
aoqi@1 1354 default:
aoqi@1 1355 ShouldNotReachHere();
aoqi@1 1356 }
aoqi@1 1357
aoqi@1 1358
aoqi@1 1359 if (needs_patching) {
aoqi@1 1360 patching_epilog(patch, patch_code, to_addr->base()->as_register(), info);
aoqi@1 1361 }
aoqi@1 1362 }
aoqi@1 1363
aoqi@1 1364
aoqi@1 1365
aoqi@1 1366 void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) {
aoqi@1 1367 assert(src->is_stack(), "should not call otherwise");
aoqi@1 1368 assert(dest->is_register(), "should not call otherwise");
aoqi@1 1369 if (dest->is_single_cpu()) {
aoqi@1 1370 #ifdef _LP64
aoqi@1 1371 if (type == T_INT)
aoqi@1 1372 __ lw(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()));
aoqi@1 1373 else
aoqi@1 1374 #endif
aoqi@1 1375 __ ld_ptr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()));
aoqi@1 1376 if (type == T_ARRAY || type == T_OBJECT) {
aoqi@1 1377 __ verify_oop(dest->as_register());
aoqi@1 1378 }
aoqi@1 1379 } else if (dest->is_double_cpu()) {
aoqi@1 1380 #ifdef _LP64
aoqi@1 1381 /* java.util.concurrent.locks.ReentrantReadWriteLock$Sync::tryAcquire
aoqi@1 1382
aoqi@1 1383 88 move [stack:2|L] [a5a5|J]
aoqi@1 1384 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")
aoqi@1 1385 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")
aoqi@1 1386 0x000000556197af8c: ld a5, 0x50(sp)
aoqi@1 1387 */
aoqi@1 1388 Address src_addr_LO;
aoqi@1 1389 if (src->is_single_stack())
aoqi@1 1390 src_addr_LO = frame_map()->address_for_slot(src->single_stack_ix(),lo_word_offset_in_bytes);
aoqi@1 1391 else if (src->is_double_stack())
aoqi@1 1392 src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix(),lo_word_offset_in_bytes);
aoqi@1 1393 else
aoqi@1 1394 ShouldNotReachHere();
aoqi@1 1395 #else
aoqi@1 1396 Address src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix(),lo_word_offset_in_bytes);
aoqi@1 1397 Address src_addr_HI = frame_map()->address_for_slot(src->double_stack_ix(), hi_word_offset_in_bytes);
aoqi@1 1398 #endif
aoqi@1 1399 #ifdef _LP64
aoqi@1 1400 if (src->type() == T_INT)
aoqi@1 1401 __ lw(dest->as_register_lo(), src_addr_LO);
aoqi@1 1402 else
aoqi@1 1403 #endif
aoqi@1 1404 __ ld_ptr(dest->as_register_lo(), src_addr_LO);
aoqi@1 1405 NOT_LP64(__ ld_ptr(dest->as_register_hi(), src_addr_HI));
aoqi@1 1406 }else if (dest->is_single_fpu()) {
aoqi@1 1407 Address addr = frame_map()->address_for_slot(src->single_stack_ix());
aoqi@1 1408 __ lwc1(dest->as_float_reg(), addr);
aoqi@1 1409 } else if (dest->is_double_fpu()) {
aoqi@1 1410 Address src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix(),lo_word_offset_in_bytes);
aoqi@1 1411 #ifndef _LP64
aoqi@1 1412 Address src_addr_HI = frame_map()->address_for_slot(src->double_stack_ix(), hi_word_offset_in_bytes);
aoqi@1 1413 __ lwc1(dest->as_double_reg(), src_addr_LO);
aoqi@1 1414 __ lwc1(dest->as_double_reg()+1, src_addr_HI);
aoqi@1 1415 #else
aoqi@1 1416 __ ldc1(dest->as_double_reg(), src_addr_LO);
aoqi@1 1417 #endif
aoqi@1 1418 } else {
aoqi@1 1419 ShouldNotReachHere();
aoqi@1 1420 /*
aoqi@1 1421 assert(dest->is_single_cpu(), "cannot be anything else but a single cpu");
aoqi@1 1422 assert(type!= T_ILLEGAL, "Bad type in stack2reg")
aoqi@1 1423 Address addr = frame_map()->address_for_slot(src->single_stack_ix());
aoqi@1 1424 __ lw(dest->as_register(), addr);
aoqi@1 1425 */
aoqi@1 1426 }
aoqi@1 1427 }
aoqi@1 1428
aoqi@1 1429 void LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) {
aoqi@1 1430 if (src->is_single_stack()) {
aoqi@1 1431 /*
aoqi@1 1432 * 2012/5/23 Jin: YozoOffice(-Xcomp) corrupts in "New File -> word"
aoqi@1 1433 *
aoqi@1 1434 * [b.q.e.a.z::bw()]
aoqi@1 1435 * move [stack:15|L] [stack:17|L]
aoqi@1 1436 * 0x00000055584e7cf4: lw at, 0x78(sp) <--- error!
aoqi@1 1437 * 0x00000055584e7cf8: sw at, 0x88(sp)
aoqi@1 1438 */
aoqi@1 1439 if (type == T_OBJECT )
aoqi@1 1440 {
aoqi@1 1441 __ ld(AT, frame_map()->address_for_slot(src ->single_stack_ix()));
aoqi@1 1442 __ sd(AT, frame_map()->address_for_slot(dest->single_stack_ix()));
aoqi@1 1443 }
aoqi@1 1444 else
aoqi@1 1445 {
aoqi@1 1446 __ lw(AT, frame_map()->address_for_slot(src ->single_stack_ix()));
aoqi@1 1447 __ sw(AT, frame_map()->address_for_slot(dest->single_stack_ix()));
aoqi@1 1448 }
aoqi@1 1449 } else if (src->is_double_stack()) {
aoqi@1 1450 #ifndef _LP64
aoqi@1 1451 __ lw(AT, frame_map()->address_for_slot(src ->double_stack_ix()));
aoqi@1 1452 __ sw(AT, frame_map()->address_for_slot(dest->double_stack_ix()));
aoqi@1 1453 __ lw(AT, frame_map()->address_for_slot(src ->double_stack_ix(),4));
aoqi@1 1454 __ sw(AT, frame_map()->address_for_slot(dest ->double_stack_ix(),4));
aoqi@1 1455 #else
aoqi@1 1456 __ ld_ptr(AT, frame_map()->address_for_slot(src ->double_stack_ix()));
aoqi@1 1457 __ st_ptr(AT, frame_map()->address_for_slot(dest->double_stack_ix()));
aoqi@1 1458 #endif
aoqi@1 1459 } else {
aoqi@1 1460 ShouldNotReachHere();
aoqi@1 1461 }
aoqi@1 1462 }
aoqi@1 1463
aoqi@1 1464 // if patching needed, be sure the instruction at offset is a MoveMemReg
aoqi@1 1465 void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool) {
aoqi@1 1466 assert(src->is_address(), "should not call otherwise");
aoqi@1 1467 assert(dest->is_register(), "should not call otherwise");
aoqi@1 1468 LIR_Address* addr = src->as_address_ptr();
aoqi@1 1469 //Address from_addr = as_Address(addr);
aoqi@1 1470
aoqi@1 1471 //Register src_reg = addr->base()->as_register();
aoqi@1 1472 // FIXME aoqi
aoqi@1 1473 Register src_reg = addr->base()->is_single_cpu()? addr->base()->as_register() : addr->base()->as_register_lo();
aoqi@1 1474 Register disp_reg = noreg;
aoqi@1 1475 int disp_value = addr->disp();
aoqi@1 1476 bool needs_patching = (patch_code != lir_patch_none);
aoqi@1 1477
aoqi@1 1478 PatchingStub* patch = NULL;
aoqi@1 1479 if (needs_patching) {
aoqi@1 1480 patch = new PatchingStub(_masm, PatchingStub::access_field_id);
aoqi@1 1481 }
aoqi@1 1482
aoqi@1 1483 // we must use lui&addiu,
aoqi@1 1484 if (needs_patching) {
aoqi@1 1485 disp_reg = AT;
aoqi@1 1486 __ lui(AT, Assembler::split_high(disp_value));
aoqi@1 1487 __ addiu(AT, AT, Assembler::split_low(disp_value));
aoqi@1 1488 } else if (!Assembler::is_simm16(disp_value)) {
aoqi@1 1489 disp_reg = AT;
aoqi@1 1490 __ lui(AT, Assembler::split_high(disp_value));
aoqi@1 1491 }
aoqi@1 1492
aoqi@1 1493 // remember the offset of the load. The patching_epilog must be done
aoqi@1 1494 // before the call to add_debug_info, otherwise the PcDescs don't get
aoqi@1 1495 // entered in increasing order.
aoqi@1 1496 int offset = code_offset();
aoqi@1 1497
aoqi@1 1498 switch(type) {
aoqi@1 1499 case T_BOOLEAN:
aoqi@1 1500 case T_BYTE: {
aoqi@1 1501 //assert(to_reg.is_word(), "just check");
aoqi@1 1502 if (disp_reg == noreg) {
aoqi@1 1503 __ lb(dest->as_register(), src_reg, disp_value);
aoqi@1 1504 } else if (needs_patching) {
aoqi@1 1505 __ add(AT, src_reg, disp_reg);
aoqi@1 1506 offset = code_offset();
aoqi@1 1507 __ lb(dest->as_register(), AT, 0);
aoqi@1 1508 } else {
aoqi@1 1509 __ add(AT, src_reg, disp_reg);
aoqi@1 1510 offset = code_offset();
aoqi@1 1511 __ lb(dest->as_register(), AT, Assembler::split_low(disp_value));
aoqi@1 1512 }
aoqi@1 1513 }
aoqi@1 1514 break;
aoqi@1 1515
aoqi@1 1516 case T_CHAR: {
aoqi@1 1517 //assert(to_reg.is_word(), "just check");
aoqi@1 1518 if (disp_reg == noreg) {
aoqi@1 1519 __ lhu(dest->as_register(), src_reg, disp_value);
aoqi@1 1520 } else if (needs_patching) {
aoqi@1 1521 __ add(AT, src_reg, disp_reg);
aoqi@1 1522 offset = code_offset();
aoqi@1 1523 __ lhu(dest->as_register(), AT, 0);
aoqi@1 1524 } else {
aoqi@1 1525 __ add(AT, src_reg, disp_reg);
aoqi@1 1526 offset = code_offset();
aoqi@1 1527 __ lhu(dest->as_register(), AT, Assembler::split_low(disp_value));
aoqi@1 1528 }
aoqi@1 1529 }
aoqi@1 1530 break;
aoqi@1 1531
aoqi@1 1532 case T_SHORT: {
aoqi@1 1533 // assert(to_reg.is_word(), "just check");
aoqi@1 1534 if (disp_reg == noreg) {
aoqi@1 1535 __ lh(dest->as_register(), src_reg, disp_value);
aoqi@1 1536 } else if (needs_patching) {
aoqi@1 1537 __ add(AT, src_reg, disp_reg);
aoqi@1 1538 offset = code_offset();
aoqi@1 1539 __ lh(dest->as_register(), AT, 0);
aoqi@1 1540 } else {
aoqi@1 1541 __ add(AT, src_reg, disp_reg);
aoqi@1 1542 offset = code_offset();
aoqi@1 1543 __ lh(dest->as_register(), AT, Assembler::split_low(disp_value));
aoqi@1 1544 }
aoqi@1 1545 }
aoqi@1 1546 break;
aoqi@1 1547
aoqi@1 1548 case T_OBJECT:
aoqi@1 1549 case T_ARRAY:
aoqi@1 1550 if (UseCompressedOops && !wide) {
aoqi@1 1551 if (disp_reg == noreg) {
aoqi@1 1552 __ lw(dest->as_register(), src_reg, disp_value);
aoqi@1 1553 } else if (needs_patching) {
aoqi@1 1554 __ dadd(AT, src_reg, disp_reg);
aoqi@1 1555 offset = code_offset();
aoqi@1 1556 __ lw(dest->as_register(), AT, 0);
aoqi@1 1557 } else {
aoqi@1 1558 __ dadd(AT, src_reg, disp_reg);
aoqi@1 1559 offset = code_offset();
aoqi@1 1560 __ lw(dest->as_register(), AT, Assembler::split_low(disp_value));
aoqi@1 1561 }
aoqi@1 1562
aoqi@1 1563 } else {
aoqi@1 1564 if (disp_reg == noreg) {
aoqi@1 1565 __ ld_ptr(dest->as_register(), src_reg, disp_value);
aoqi@1 1566 } else if (needs_patching) {
aoqi@1 1567 __ dadd(AT, src_reg, disp_reg);
aoqi@1 1568 offset = code_offset();
aoqi@1 1569 __ ld_ptr(dest->as_register(), AT, 0);
aoqi@1 1570 } else {
aoqi@1 1571 __ dadd(AT, src_reg, disp_reg);
aoqi@1 1572 offset = code_offset();
aoqi@1 1573 __ ld_ptr(dest->as_register(), AT, Assembler::split_low(disp_value));
aoqi@1 1574 }
aoqi@1 1575 }
aoqi@1 1576 break;
aoqi@1 1577 case T_ADDRESS:
aoqi@1 1578 if (disp_reg == noreg) {
aoqi@1 1579 __ ld_ptr(dest->as_register(), src_reg, disp_value);
aoqi@1 1580 } else if (needs_patching) {
aoqi@1 1581 __ dadd(AT, src_reg, disp_reg);
aoqi@1 1582 offset = code_offset();
aoqi@1 1583 __ ld_ptr(dest->as_register(), AT, 0);
aoqi@1 1584 } else {
aoqi@1 1585 __ dadd(AT, src_reg, disp_reg);
aoqi@1 1586 offset = code_offset();
aoqi@1 1587 __ ld_ptr(dest->as_register(), AT, Assembler::split_low(disp_value));
aoqi@1 1588 }
aoqi@1 1589 break;
aoqi@1 1590 case T_INT: {
aoqi@1 1591 //assert(to_reg.is_word(), "just check");
aoqi@1 1592 if (disp_reg == noreg) {
aoqi@1 1593 __ lw(dest->as_register(), src_reg, disp_value);
aoqi@1 1594 } else if (needs_patching) {
aoqi@1 1595 __ add(AT, src_reg, disp_reg);
aoqi@1 1596 offset = code_offset();
aoqi@1 1597 __ lw(dest->as_register(), AT, 0);
aoqi@1 1598 } else {
aoqi@1 1599 __ add(AT, src_reg, disp_reg);
aoqi@1 1600 offset = code_offset();
aoqi@1 1601 __ lw(dest->as_register(), AT, Assembler::split_low(disp_value));
aoqi@1 1602 }
aoqi@1 1603 }
aoqi@1 1604 break;
aoqi@1 1605
aoqi@1 1606 case T_LONG: {
aoqi@1 1607 Register to_lo = dest->as_register_lo();
aoqi@1 1608 Register to_hi = dest->as_register_hi();
aoqi@1 1609 #ifdef _LP64
aoqi@1 1610 if (needs_patching) {
aoqi@1 1611 __ add(AT, src_reg, disp_reg);
aoqi@1 1612 __ ld_ptr(to_lo, AT, 0);
aoqi@1 1613 } else {
aoqi@1 1614 __ ld_ptr(to_lo, as_Address_lo(addr));
aoqi@1 1615 }
aoqi@1 1616 #else
aoqi@1 1617 Register base = addr->base()->as_register();
aoqi@1 1618 Register index = noreg;
aoqi@1 1619 if (addr->index()->is_register()) {
aoqi@1 1620 index = addr->index()->as_register();
aoqi@1 1621 }
aoqi@1 1622 if ((base == to_lo && index == to_hi) ||(base == to_hi && index == to_lo)) {
aoqi@1 1623 // addresses with 2 registers are only formed as a result of
aoqi@1 1624 // array access so this code will never have to deal with
aoqi@1 1625 // patches or null checks.
aoqi@1 1626 assert(info == NULL && patch == NULL, "must be");
aoqi@1 1627 __ lea(to_hi, as_Address(addr));
aoqi@1 1628 __ lw(to_lo, Address(to_hi));
aoqi@1 1629 __ lw(to_hi, Address(to_hi, BytesPerWord));
aoqi@1 1630 } else if (base == to_lo || index == to_lo) {
aoqi@1 1631 assert(base != to_hi, "can't be");
aoqi@1 1632 assert(index == noreg || (index != base && index != to_hi), "can't handle this");
aoqi@1 1633 if (needs_patching) {
aoqi@1 1634 __ add(AT, src_reg, disp_reg);
aoqi@1 1635 offset = code_offset();
aoqi@1 1636 __ lw(to_hi, AT, longSize/2);
aoqi@1 1637 __ lw(to_lo, AT, 0);
aoqi@1 1638 } else {
aoqi@1 1639 __ lw(to_hi, as_Address_hi(addr));
aoqi@1 1640 __ lw(to_lo, as_Address_lo(addr));
aoqi@1 1641 }
aoqi@1 1642 } else {
aoqi@1 1643 assert(index == noreg || (index != base && index != to_lo), "can't handle this");
aoqi@1 1644 if (needs_patching) {
aoqi@1 1645 __ add(AT, src_reg, disp_reg);
aoqi@1 1646 offset = code_offset();
aoqi@1 1647 __ lw(to_lo, AT, 0);
aoqi@1 1648 __ lw(to_hi, AT, longSize/2);
aoqi@1 1649 } else {
aoqi@1 1650 __ lw(to_lo, as_Address_lo(addr));
aoqi@1 1651 __ lw(to_hi, as_Address_hi(addr));
aoqi@1 1652 }
aoqi@1 1653 }
aoqi@1 1654 #endif
aoqi@1 1655 }
aoqi@1 1656 break;
aoqi@1 1657
aoqi@1 1658 case T_FLOAT: {
aoqi@1 1659 //assert(to_reg.is_float(), "just check");
aoqi@1 1660 if (disp_reg == noreg) {
aoqi@1 1661 __ lwc1(dest->as_float_reg(), src_reg, disp_value);
aoqi@1 1662 } else if (needs_patching) {
aoqi@1 1663 __ add(AT, src_reg, disp_reg);
aoqi@1 1664 offset = code_offset();
aoqi@1 1665 __ lwc1(dest->as_float_reg(), AT, 0);
aoqi@1 1666 } else {
aoqi@1 1667 __ add(AT, src_reg, disp_reg);
aoqi@1 1668 offset = code_offset();
aoqi@1 1669 __ lwc1(dest->as_float_reg(), AT, Assembler::split_low(disp_value));
aoqi@1 1670 }
aoqi@1 1671 }
aoqi@1 1672 break;
aoqi@1 1673
aoqi@1 1674 case T_DOUBLE: {
aoqi@1 1675 //assert(to_reg.is_double(), "just check");
aoqi@1 1676
aoqi@1 1677 if (disp_reg == noreg) {
aoqi@1 1678 #ifndef _LP64
aoqi@1 1679 __ lwc1(dest->as_double_reg(), src_reg, disp_value);
aoqi@1 1680 __ lwc1(dest->as_double_reg()+1, src_reg, disp_value+4);
aoqi@1 1681 #else
aoqi@1 1682 __ ldc1(dest->as_double_reg(), src_reg, disp_value);
aoqi@1 1683 #endif
aoqi@1 1684 } else if (needs_patching) {
aoqi@1 1685 __ add(AT, src_reg, disp_reg);
aoqi@1 1686 offset = code_offset();
aoqi@1 1687 #ifndef _LP64
aoqi@1 1688 __ lwc1(dest->as_double_reg(), AT, 0);
aoqi@1 1689 __ lwc1(dest->as_double_reg()+1, AT, 4);
aoqi@1 1690 #else
aoqi@1 1691 __ ldc1(dest->as_double_reg(), AT, 0);
aoqi@1 1692 #endif
aoqi@1 1693 } else {
aoqi@1 1694 __ add(AT, src_reg, disp_reg);
aoqi@1 1695 offset = code_offset();
aoqi@1 1696 #ifndef _LP64
aoqi@1 1697 __ lwc1(dest->as_double_reg(), AT, Assembler::split_low(disp_value));
aoqi@1 1698 __ lwc1(dest->as_double_reg()+1, AT, Assembler::split_low(disp_value) + 4);
aoqi@1 1699 #else
aoqi@1 1700 __ ldc1(dest->as_double_reg(), AT, Assembler::split_low(disp_value));
aoqi@1 1701 #endif
aoqi@1 1702 }
aoqi@1 1703 }
aoqi@1 1704 break;
aoqi@1 1705
aoqi@1 1706 default:
aoqi@1 1707 ShouldNotReachHere();
aoqi@1 1708 }
aoqi@1 1709
aoqi@1 1710 if (needs_patching) {
aoqi@1 1711 patching_epilog(patch, patch_code, src_reg, info);
aoqi@1 1712 }
aoqi@1 1713
aoqi@1 1714 if (type == T_ARRAY || type == T_OBJECT) {
aoqi@1 1715 #ifdef _LP64
aoqi@1 1716 if (UseCompressedOops && !wide) {
aoqi@1 1717 __ decode_heap_oop(dest->as_register());
aoqi@1 1718 }
aoqi@1 1719 #endif
aoqi@1 1720 __ verify_oop(dest->as_register());
aoqi@1 1721 }
aoqi@1 1722 if (info != NULL) add_debug_info_for_null_check(offset, info);
aoqi@1 1723 }
aoqi@1 1724
aoqi@1 1725
aoqi@1 1726 void LIR_Assembler::prefetchr(LIR_Opr src) {
aoqi@1 1727 LIR_Address* addr = src->as_address_ptr();
aoqi@1 1728 Address from_addr = as_Address(addr);
aoqi@1 1729 }
aoqi@1 1730
aoqi@1 1731
aoqi@1 1732 void LIR_Assembler::prefetchw(LIR_Opr src) {
aoqi@1 1733 }
aoqi@1 1734
aoqi@1 1735 NEEDS_CLEANUP; // This could be static?
aoqi@1 1736 Address::ScaleFactor LIR_Assembler::array_element_size(BasicType type) const {
aoqi@1 1737 int elem_size = type2aelembytes(type);
aoqi@1 1738 switch (elem_size) {
aoqi@1 1739 case 1: return Address::times_1;
aoqi@1 1740 case 2: return Address::times_2;
aoqi@1 1741 case 4: return Address::times_4;
aoqi@1 1742 case 8: return Address::times_8;
aoqi@1 1743 }
aoqi@1 1744 ShouldNotReachHere();
aoqi@1 1745 return Address::no_scale;
aoqi@1 1746 }
aoqi@1 1747
aoqi@1 1748
aoqi@1 1749 void LIR_Assembler::emit_op3(LIR_Op3* op) {
aoqi@1 1750 switch (op->code()) {
aoqi@1 1751 case lir_frem:
aoqi@1 1752 arithmetic_frem(
aoqi@1 1753 op->code(),
aoqi@1 1754 op->in_opr1(),
aoqi@1 1755 op->in_opr2(),
aoqi@1 1756 op->in_opr3(),
aoqi@1 1757 op->result_opr(),
aoqi@1 1758 op->info());
aoqi@1 1759 break;
aoqi@1 1760
aoqi@1 1761 case lir_idiv:
aoqi@1 1762 case lir_irem:
aoqi@1 1763 arithmetic_idiv(
aoqi@1 1764 op->code(),
aoqi@1 1765 op->in_opr1(),
aoqi@1 1766 op->in_opr2(),
aoqi@1 1767 op->in_opr3(),
aoqi@1 1768 op->result_opr(),
aoqi@1 1769 op->info());
aoqi@1 1770 break;
aoqi@1 1771 default: ShouldNotReachHere(); break;
aoqi@1 1772 }
aoqi@1 1773 }
aoqi@1 1774
aoqi@1 1775 void LIR_Assembler::emit_opBranch(LIR_OpBranch* op) {
aoqi@1 1776 LIR_Opr opr1 = op->left();
aoqi@1 1777 LIR_Opr opr2 = op->right();
aoqi@1 1778 LIR_Condition condition = op->cond();
aoqi@1 1779 #ifdef ASSERT
aoqi@1 1780 assert(op->block() == NULL || op->block()->label() == op->label(), "wrong label");
aoqi@1 1781 if (op->block() != NULL) _branch_target_blocks.append(op->block());
aoqi@1 1782 if (op->ublock() != NULL) _branch_target_blocks.append(op->ublock());
aoqi@1 1783 #endif
aoqi@1 1784 if (op->cond() == lir_cond_always) {
aoqi@1 1785 if(op->label()==NULL) //by liaob1
aoqi@1 1786 __ b(*op->label());
aoqi@1 1787 else
aoqi@1 1788 __ b_far(*op->label());
aoqi@1 1789 __ delayed()->nop();
aoqi@1 1790 return;
aoqi@1 1791 }
aoqi@1 1792 if (opr1->is_single_cpu()) {
aoqi@1 1793 Register reg_op1 = opr1->as_register();
aoqi@1 1794 if (opr2->is_single_cpu()) {
aoqi@1 1795 #ifdef OPT_RANGECHECK
aoqi@1 1796 assert(!op->check(), "just check");
aoqi@1 1797 #endif
aoqi@1 1798 Register reg_op2 = opr2->as_register();
aoqi@1 1799 switch (condition) {
aoqi@1 1800 case lir_cond_equal:
aoqi@1 1801 __ beq(reg_op1, reg_op2, *op->label());
aoqi@1 1802 break;
aoqi@1 1803 case lir_cond_notEqual:
aoqi@1 1804 if(op->label()==NULL)
aoqi@1 1805 __ bne(reg_op1, reg_op2, *op->label());//liaobin1
aoqi@1 1806 else
aoqi@1 1807 __ bne_far(reg_op1, reg_op2, *op->label());//liaobin1
aoqi@1 1808 break;
aoqi@1 1809 case lir_cond_less:
aoqi@1 1810 // AT = 1 TRUE
aoqi@1 1811 __ slt(AT, reg_op1, reg_op2);
aoqi@1 1812 __ bne_far(AT, R0, *op->label());
aoqi@1 1813 break;
aoqi@1 1814 case lir_cond_lessEqual:
aoqi@1 1815 // AT = 0 TRUE
aoqi@1 1816 __ slt(AT, reg_op2, reg_op1);
aoqi@1 1817 __ beq_far(AT, R0, *op->label());
aoqi@1 1818 break;
aoqi@1 1819 case lir_cond_belowEqual:
aoqi@1 1820 // AT = 0 TRUE
aoqi@1 1821 __ sltu(AT, reg_op2, reg_op1);
aoqi@1 1822 __ beq(AT, R0, *op->label());
aoqi@1 1823 break;
aoqi@1 1824 case lir_cond_greaterEqual:
aoqi@1 1825 // AT = 0 TRUE
aoqi@1 1826 __ slt(AT, reg_op1, reg_op2);
aoqi@1 1827 __ beq_far(AT, R0, *op->label());
aoqi@1 1828 break;
aoqi@1 1829 case lir_cond_aboveEqual:
aoqi@1 1830 // AT = 0 TRUE
aoqi@1 1831 __ sltu(AT, reg_op1, reg_op2);
aoqi@1 1832 __ beq_far(AT, R0, *op->label());
aoqi@1 1833 break;
aoqi@1 1834 case lir_cond_greater:
aoqi@1 1835 // AT = 1 TRUE
aoqi@1 1836 __ slt(AT, reg_op2, reg_op1);
aoqi@1 1837 __ bne_far(AT, R0, *op->label());
aoqi@1 1838 break;
aoqi@1 1839 default: ShouldNotReachHere();
aoqi@1 1840 }
aoqi@1 1841 } else if (opr2->is_constant()) {
aoqi@1 1842 NOT_LP64(jint) LP64_ONLY(jlong) temp_value;
aoqi@1 1843 bool is_object = false;
aoqi@1 1844 if (opr2->pointer()->as_constant()->type() == T_INT) {
aoqi@1 1845 temp_value = (jint)(opr2->as_jint());
aoqi@1 1846 } else if (opr2->pointer()->as_constant()->type() == T_LONG) {
aoqi@1 1847 temp_value = (jlong)(opr2->as_jlong());
aoqi@1 1848 } else if (opr2->pointer()->as_constant()->type() == T_OBJECT) {
aoqi@1 1849 is_object = true;
aoqi@1 1850 temp_value = NOT_LP64((jint)) LP64_ONLY((jlong))(opr2->as_jobject());
aoqi@1 1851 } else {
aoqi@1 1852 ShouldNotReachHere();
aoqi@1 1853 }
aoqi@1 1854
aoqi@1 1855 switch (condition) {
aoqi@1 1856 case lir_cond_equal:
aoqi@1 1857 #ifdef OPT_RANGECHECK
aoqi@1 1858 assert(!op->check(), "just check");
aoqi@1 1859 #endif
aoqi@1 1860 if (temp_value) {
aoqi@1 1861 if (is_object) {
aoqi@1 1862 int oop_index = __ oop_recorder()->allocate_oop_index((jobject)temp_value);
aoqi@1 1863 RelocationHolder rspec = oop_Relocation::spec(oop_index);
aoqi@1 1864 __ relocate(rspec);
aoqi@1 1865 }
aoqi@1 1866 __ li(AT, temp_value);
aoqi@1 1867 __ beq_far(reg_op1, AT, *op->label());
aoqi@1 1868 } else {
aoqi@1 1869 __ beq_far(reg_op1, R0, *op->label());
aoqi@1 1870 }
aoqi@1 1871 break;
aoqi@1 1872
aoqi@1 1873 case lir_cond_notEqual:
aoqi@1 1874 #ifdef OPT_RANGECHECK
aoqi@1 1875 assert(!op->check(), "just check");
aoqi@1 1876 #endif
aoqi@1 1877 if (temp_value) {
aoqi@1 1878 if (is_object) {
aoqi@1 1879 int oop_index = __ oop_recorder()->allocate_oop_index((jobject)temp_value);
aoqi@1 1880 RelocationHolder rspec = oop_Relocation::spec(oop_index);
aoqi@1 1881 __ relocate(rspec);
aoqi@1 1882 }
aoqi@1 1883 __ li(AT, temp_value);
aoqi@1 1884 __ bne_far(reg_op1, AT, *op->label());
aoqi@1 1885 } else {
aoqi@1 1886 __ bne_far(reg_op1, R0, *op->label());
aoqi@1 1887 }
aoqi@1 1888 break;
aoqi@1 1889
aoqi@1 1890 case lir_cond_less:
aoqi@1 1891 #ifdef OPT_RANGECHECK
aoqi@1 1892 assert(!op->check(), "just check");
aoqi@1 1893 #endif
aoqi@1 1894 // AT = 1 TRUE
aoqi@1 1895 if (Assembler::is_simm16(temp_value)) {
aoqi@1 1896 __ slti(AT, reg_op1, temp_value);
aoqi@1 1897 } else {
aoqi@1 1898 __ move(AT, temp_value);
aoqi@1 1899 __ slt(AT, reg_op1, AT);
aoqi@1 1900 }
aoqi@1 1901 __ bne_far(AT, R0, *op->label());
aoqi@1 1902 break;
aoqi@1 1903
aoqi@1 1904 case lir_cond_lessEqual:
aoqi@1 1905 #ifdef OPT_RANGECHECK
aoqi@1 1906 assert(!op->check(), "just check");
aoqi@1 1907 #endif
aoqi@1 1908 // AT = 0 TRUE
aoqi@1 1909 __ li(AT, temp_value);
aoqi@1 1910 __ slt(AT, AT, reg_op1);
aoqi@1 1911 __ beq(AT, R0, *op->label());
aoqi@1 1912 break;
aoqi@1 1913
aoqi@1 1914 case lir_cond_belowEqual:
aoqi@1 1915 // AT = 0 TRUE
aoqi@1 1916 #ifdef OPT_RANGECHECK
aoqi@1 1917 if (op->check()) {
aoqi@1 1918 __ li(AT, temp_value);
aoqi@1 1919 add_debug_info_for_range_check_here(op->info(), temp_value);
aoqi@1 1920 __ tgeu(AT, reg_op1, 29);
aoqi@1 1921 } else {
aoqi@1 1922 #endif
aoqi@1 1923 __ li(AT, temp_value);
aoqi@1 1924 __ sltu(AT, AT, reg_op1);
aoqi@1 1925 __ beq(AT, R0, *op->label());
aoqi@1 1926 #ifdef OPT_RANGECHECK
aoqi@1 1927 }
aoqi@1 1928 #endif
aoqi@1 1929 break;
aoqi@1 1930
aoqi@1 1931 case lir_cond_greaterEqual:
aoqi@1 1932 #ifdef OPT_RANGECHECK
aoqi@1 1933 assert(!op->check(), "just check");
aoqi@1 1934 #endif
aoqi@1 1935 // AT = 0 TRUE
aoqi@1 1936 if (Assembler::is_simm16(temp_value)) {
aoqi@1 1937 __ slti(AT, reg_op1, temp_value);
aoqi@1 1938 } else {
aoqi@1 1939 __ li(AT, temp_value);
aoqi@1 1940 __ slt(AT, reg_op1, AT);
aoqi@1 1941 }
aoqi@1 1942 __ beq(AT, R0, *op->label());
aoqi@1 1943 break;
aoqi@1 1944
aoqi@1 1945 case lir_cond_aboveEqual:
aoqi@1 1946 #ifdef OPT_RANGECHECK
aoqi@1 1947 assert(!op->check(), "just check");
aoqi@1 1948 #endif
aoqi@1 1949 // AT = 0 TRUE
aoqi@1 1950 if (Assembler::is_simm16(temp_value)) {
aoqi@1 1951 __ sltiu(AT, reg_op1, temp_value);
aoqi@1 1952 } else {
aoqi@1 1953 __ li(AT, temp_value);
aoqi@1 1954 __ sltu(AT, reg_op1, AT);
aoqi@1 1955 }
aoqi@1 1956 __ beq(AT, R0, *op->label());
aoqi@1 1957 break;
aoqi@1 1958
aoqi@1 1959 case lir_cond_greater:
aoqi@1 1960 #ifdef OPT_RANGECHECK
aoqi@1 1961 assert(!op->check(), "just check");
aoqi@1 1962 #endif
aoqi@1 1963 // AT = 1 TRUE
aoqi@1 1964 __ li(AT, temp_value);
aoqi@1 1965 __ slt(AT, AT, reg_op1);
aoqi@1 1966 __ bne_far(AT, R0, *op->label());
aoqi@1 1967 break;
aoqi@1 1968
aoqi@1 1969 default: ShouldNotReachHere();
aoqi@1 1970 }
aoqi@1 1971
aoqi@1 1972 } else {
aoqi@1 1973 if (opr2->is_address()) {
aoqi@1 1974 //FIXME. aoqi lw or ld_ptr?
aoqi@1 1975 if (op->type() == T_INT)
aoqi@1 1976 __ lw(AT, as_Address(opr2->pointer()->as_address()));
aoqi@1 1977 else
aoqi@1 1978 __ ld_ptr(AT, as_Address(opr2->pointer()->as_address()));
aoqi@1 1979 } else if (opr2->is_stack()) {
aoqi@1 1980 //FIXME. aoqi
aoqi@1 1981 __ ld_ptr(AT, frame_map()->address_for_slot(opr2->single_stack_ix()));
aoqi@1 1982 } else {
aoqi@1 1983 ShouldNotReachHere();
aoqi@1 1984 }
aoqi@1 1985 switch (condition) {
aoqi@1 1986 case lir_cond_equal:
aoqi@1 1987 #ifdef OPT_RANGECHECK
aoqi@1 1988 assert(!op->check(), "just check");
aoqi@1 1989 #endif
aoqi@1 1990 __ beq(reg_op1, AT, *op->label());
aoqi@1 1991 break;
aoqi@1 1992 case lir_cond_notEqual:
aoqi@1 1993 #ifdef OPT_RANGECHECK
aoqi@1 1994 assert(!op->check(), "just check");
aoqi@1 1995 #endif
aoqi@1 1996 __ bne_far(reg_op1, AT, *op->label());
aoqi@1 1997 break;
aoqi@1 1998 case lir_cond_less:
aoqi@1 1999 #ifdef OPT_RANGECHECK
aoqi@1 2000 assert(!op->check(), "just check");
aoqi@1 2001 #endif
aoqi@1 2002 // AT = 1 TRUE
aoqi@1 2003 __ slt(AT, reg_op1, AT);
aoqi@1 2004 __ bne_far(AT, R0, *op->label());
aoqi@1 2005 break;
aoqi@1 2006 case lir_cond_lessEqual:
aoqi@1 2007 #ifdef OPT_RANGECHECK
aoqi@1 2008 assert(!op->check(), "just check");
aoqi@1 2009 #endif
aoqi@1 2010 // AT = 0 TRUE
aoqi@1 2011 __ slt(AT, AT, reg_op1);
aoqi@1 2012 __ beq(AT, R0, *op->label());
aoqi@1 2013 break;
aoqi@1 2014 case lir_cond_belowEqual:
aoqi@1 2015 #ifdef OPT_RANGECHECK
aoqi@1 2016 assert(!op->check(), "just check");
aoqi@1 2017 #endif
aoqi@1 2018 // AT = 0 TRUE
aoqi@1 2019 __ sltu(AT, AT, reg_op1);
aoqi@1 2020 __ beq(AT, R0, *op->label());
aoqi@1 2021 break;
aoqi@1 2022 case lir_cond_greaterEqual:
aoqi@1 2023 #ifdef OPT_RANGECHECK
aoqi@1 2024 assert(!op->check(), "just check");
aoqi@1 2025 #endif
aoqi@1 2026 // AT = 0 TRUE
aoqi@1 2027 __ slt(AT, reg_op1, AT);
aoqi@1 2028 __ beq(AT, R0, *op->label());
aoqi@1 2029 break;
aoqi@1 2030 case lir_cond_aboveEqual:
aoqi@1 2031 // AT = 0 TRUE
aoqi@1 2032 #ifdef OPT_RANGECHECK
aoqi@1 2033 if (op->check()) {
aoqi@1 2034 add_debug_info_for_range_check_here(op->info(), opr1->rinfo());
aoqi@1 2035 __ tgeu(reg_op1, AT, 29);
aoqi@1 2036 } else {
aoqi@1 2037 #endif
aoqi@1 2038 __ sltu(AT, reg_op1, AT);
aoqi@1 2039 __ beq_far(AT, R0, *op->label());
aoqi@1 2040 #ifdef OPT_RANGECHECK
aoqi@1 2041 }
aoqi@1 2042 #endif
aoqi@1 2043 break;
aoqi@1 2044 case lir_cond_greater:
aoqi@1 2045 #ifdef OPT_RANGECHECK
aoqi@1 2046 assert(!op->check(), "just check");
aoqi@1 2047 #endif
aoqi@1 2048 // AT = 1 TRUE
aoqi@1 2049 __ slt(AT, AT, reg_op1);
aoqi@1 2050 __ bne_far(AT, R0, *op->label());
aoqi@1 2051 break;
aoqi@1 2052 default: ShouldNotReachHere();
aoqi@1 2053 }
aoqi@1 2054 }
aoqi@1 2055 #ifdef OPT_RANGECHECK
aoqi@1 2056 if (!op->check())
aoqi@1 2057 #endif
aoqi@1 2058 __ delayed()->nop();
aoqi@1 2059
aoqi@1 2060 } else if(opr1->is_address() || opr1->is_stack()) {
aoqi@1 2061 #ifdef OPT_RANGECHECK
aoqi@1 2062 assert(!op->check(), "just check");
aoqi@1 2063 #endif
aoqi@1 2064 if (opr2->is_constant()) {
aoqi@1 2065 NOT_LP64(jint) LP64_ONLY(jlong) temp_value;
aoqi@1 2066 if (opr2->as_constant_ptr()->type() == T_INT) {
aoqi@1 2067 temp_value = (jint)opr2->as_constant_ptr()->as_jint();
aoqi@1 2068 } else if (opr2->as_constant_ptr()->type() == T_OBJECT) {
aoqi@1 2069 temp_value = NOT_LP64((jint)) LP64_ONLY((jlong))(opr2->as_constant_ptr()->as_jobject());
aoqi@1 2070 } else {
aoqi@1 2071 ShouldNotReachHere();
aoqi@1 2072 }
aoqi@1 2073
aoqi@1 2074 if (Assembler::is_simm16(temp_value)) {
aoqi@1 2075 if (opr1->is_address()) {
aoqi@1 2076 __ lw(AT, as_Address(opr1->pointer()->as_address()));
aoqi@1 2077 } else {
aoqi@1 2078 __ lw(AT, frame_map()->address_for_slot(opr1->single_stack_ix()));
aoqi@1 2079 }
aoqi@1 2080
aoqi@1 2081 switch(condition) {
aoqi@1 2082
aoqi@1 2083 case lir_cond_equal:
aoqi@1 2084 __ addi(AT, AT, -(int)temp_value);
aoqi@1 2085 __ beq(AT, R0, *op->label());
aoqi@1 2086 break;
aoqi@1 2087 case lir_cond_notEqual:
aoqi@1 2088 __ addi(AT, AT, -(int)temp_value);
aoqi@1 2089 __ bne_far(AT, R0, *op->label());
aoqi@1 2090 break;
aoqi@1 2091 case lir_cond_less:
aoqi@1 2092 // AT = 1 TRUE
aoqi@1 2093 __ slti(AT, AT, temp_value);
aoqi@1 2094 __ bne_far(AT, R0, *op->label());
aoqi@1 2095 break;
aoqi@1 2096 case lir_cond_lessEqual:
aoqi@1 2097 // AT = 0 TRUE
aoqi@1 2098 __ addi(AT, AT, -temp_value);
aoqi@1 2099 __ slt(AT, R0, AT);
aoqi@1 2100 __ beq(AT, R0, *op->label());
aoqi@1 2101 break;
aoqi@1 2102 case lir_cond_belowEqual:
aoqi@1 2103 // AT = 0 TRUE
aoqi@1 2104 __ addiu(AT, AT, -temp_value);
aoqi@1 2105 __ sltu(AT, R0, AT);
aoqi@1 2106 __ beq(AT, R0, *op->label());
aoqi@1 2107 break;
aoqi@1 2108 case lir_cond_greaterEqual:
aoqi@1 2109 // AT = 0 TRUE
aoqi@1 2110 __ slti(AT, AT, temp_value);
aoqi@1 2111 __ beq(AT, R0, *op->label());
aoqi@1 2112 break;
aoqi@1 2113 case lir_cond_aboveEqual:
aoqi@1 2114 // AT = 0 TRUE
aoqi@1 2115 __ sltiu(AT, AT, temp_value);
aoqi@1 2116 __ beq(AT, R0, *op->label());
aoqi@1 2117 break;
aoqi@1 2118 case lir_cond_greater:
aoqi@1 2119 // AT = 1 TRUE
aoqi@1 2120 __ addi(AT, AT, -temp_value);
aoqi@1 2121 __ slt(AT, R0, AT);
aoqi@1 2122 __ bne_far(AT, R0, *op->label());
aoqi@1 2123 break;
aoqi@1 2124
aoqi@1 2125 default:
aoqi@1 2126 Unimplemented();
aoqi@1 2127 }
aoqi@1 2128 } else {
aoqi@1 2129 Unimplemented();
aoqi@1 2130 }
aoqi@1 2131 } else {
aoqi@1 2132 Unimplemented();
aoqi@1 2133 }
aoqi@1 2134 __ delayed()->nop();
aoqi@1 2135
aoqi@1 2136 } else if(opr1->is_double_cpu()) {
aoqi@1 2137 #ifdef OPT_RANGECHECK
aoqi@1 2138 assert(!op->check(), "just check");
aoqi@1 2139 #endif
aoqi@1 2140 Register opr1_lo = opr1->as_register_lo();
aoqi@1 2141 Register opr1_hi = opr1->as_register_hi();
aoqi@1 2142
aoqi@1 2143 if (opr2->is_double_cpu()) {
aoqi@1 2144 Register opr2_lo = opr2->as_register_lo();
aoqi@1 2145 Register opr2_hi = opr2->as_register_hi();
aoqi@1 2146 switch (condition) {
aoqi@1 2147 case lir_cond_equal: {
aoqi@1 2148 Label L;
aoqi@1 2149 #ifndef _LP64
aoqi@1 2150 __ bne(opr1_lo, opr2_lo, L);
aoqi@1 2151 __ delayed()->nop();
aoqi@1 2152 __ beq(opr1_hi, opr2_hi, *op->label());
aoqi@1 2153 #else
aoqi@1 2154 /* static jobject java.lang.Long.toString(jlong)
aoqi@1 2155
aoqi@1 2156 10 move [t0t0|J] [a4a4|J]
aoqi@1 2157 12 move [lng:-9223372036854775808|J] [a6a6|J]
aoqi@1 2158 14 branch [EQ] [a4a4|J] [a6a6|J] [B1]
aoqi@1 2159 0x000000555e8532e4: bne a4, a6, 0x000000555e8532e4 <-- error
aoqi@1 2160 0x000000555e8532e8: sll zero, zero, 0
aoqi@1 2161 */
aoqi@1 2162 // __ beq(opr1_lo, opr2_lo, *op->label());
aoqi@1 2163 __ beq(opr1_lo, opr2_lo, *op->label());
aoqi@1 2164 #endif
aoqi@1 2165 __ delayed()->nop();
aoqi@1 2166 __ bind(L);
aoqi@1 2167 }
aoqi@1 2168 break;
aoqi@1 2169
aoqi@1 2170 case lir_cond_notEqual:
aoqi@1 2171 if (op->label()==NULL)
aoqi@1 2172 __ bne(opr1_lo, opr2_lo, *op->label());//by liaobin2
aoqi@1 2173 else
aoqi@1 2174 __ bne_far(opr1_lo, opr2_lo, *op->label());//by liaobin2
aoqi@1 2175 __ delayed()->nop();
aoqi@1 2176 if (op->label()==NULL)
aoqi@1 2177 NOT_LP64(__ bne(opr1_hi, opr2_hi, *op->label()));//by liaobin3
aoqi@1 2178 else
aoqi@1 2179 NOT_LP64(__ bne_far(opr1_hi, opr2_hi, *op->label()));//by liaobin3
aoqi@1 2180 NOT_LP64(__ delayed()->nop());
aoqi@1 2181 break;
aoqi@1 2182
aoqi@1 2183 case lir_cond_less: {
aoqi@1 2184 #ifdef _LP64
aoqi@1 2185 __ slt(AT, opr1_lo, opr2_lo);
aoqi@1 2186 __ bne_far(AT, R0, *op->label());
aoqi@1 2187 __ delayed()->nop();
aoqi@1 2188 #else
aoqi@1 2189 Label L;
aoqi@1 2190
aoqi@1 2191 // if hi less then jump
aoqi@1 2192 __ slt(AT, opr1_hi, opr2_hi);
aoqi@1 2193 __ bne(AT, R0, *op->label());
aoqi@1 2194 __ delayed()->nop();
aoqi@1 2195
aoqi@1 2196 // if hi great then fail
aoqi@1 2197 __ bne(opr1_hi, opr2_hi, L);
aoqi@1 2198 __ delayed();
aoqi@1 2199
aoqi@1 2200 // now just comp lo as unsigned
aoqi@1 2201 __ sltu(AT, opr1_lo, opr2_lo);
aoqi@1 2202 __ bne_far(AT, R0, *op->label());
aoqi@1 2203 __ delayed()->nop();
aoqi@1 2204
aoqi@1 2205 __ bind(L);
aoqi@1 2206 #endif
aoqi@1 2207 }
aoqi@1 2208 break;
aoqi@1 2209
aoqi@1 2210 case lir_cond_lessEqual: {
aoqi@1 2211 #ifdef _LP64
aoqi@1 2212 __ slt(AT, opr2_lo, opr1_lo);
aoqi@1 2213 __ beq_far(AT, R0, *op->label());
aoqi@1 2214 __ delayed()->nop();
aoqi@1 2215 #else
aoqi@1 2216 Label L;
aoqi@1 2217
aoqi@1 2218 // if hi great then fail
aoqi@1 2219 __ slt(AT, opr2_hi, opr1_hi);
aoqi@1 2220 __ bne(AT, R0, L);
aoqi@1 2221 __ delayed()->nop();
aoqi@1 2222
aoqi@1 2223 // if hi less then jump
aoqi@1 2224 if(op->label()==NULL)
aoqi@1 2225 __ bne(opr2_hi, opr1_hi, *op->label());//by liaobin4
aoqi@1 2226 else
aoqi@1 2227 __ bne_far(opr2_hi, opr1_hi, *op->label());//by liaobin4
aoqi@1 2228 __ delayed();
aoqi@1 2229
aoqi@1 2230 // now just comp lo as unsigned
aoqi@1 2231 __ sltu(AT, opr2_lo, opr1_lo);
aoqi@1 2232 __ beq(AT, R0, *op->label());
aoqi@1 2233 __ delayed()->nop();
aoqi@1 2234
aoqi@1 2235 __ bind(L);
aoqi@1 2236 #endif
aoqi@1 2237 }
aoqi@1 2238 break;
aoqi@1 2239
aoqi@1 2240 case lir_cond_belowEqual: {
aoqi@1 2241 #ifdef _LP64
aoqi@1 2242 __ sltu(AT, opr2_lo, opr1_lo);
aoqi@1 2243 __ beq(AT, R0, *op->label());
aoqi@1 2244 __ delayed()->nop();
aoqi@1 2245 #else
aoqi@1 2246 Label L;
aoqi@1 2247
aoqi@1 2248 // if hi great then fail
aoqi@1 2249 __ sltu(AT, opr2_hi, opr1_hi);
aoqi@1 2250 __ bne_far(AT, R0, L);
aoqi@1 2251 __ delayed()->nop();
aoqi@1 2252
aoqi@1 2253 // if hi less then jump
aoqi@1 2254 if(op->label()==NULL)
aoqi@1 2255 __ bne(opr2_hi, opr1_hi, *op->label());//by liaobin5
aoqi@1 2256 else
aoqi@1 2257 __ bne_far(opr2_hi, opr1_hi, *op->label());//by liaobin5
aoqi@1 2258 __ delayed();
aoqi@1 2259
aoqi@1 2260 // now just comp lo as unsigned
aoqi@1 2261 __ sltu(AT, opr2_lo, opr1_lo);
aoqi@1 2262 __ beq(AT, R0, *op->label());
aoqi@1 2263 __ delayed()->nop();
aoqi@1 2264
aoqi@1 2265 __ bind(L);
aoqi@1 2266 #endif
aoqi@1 2267 }
aoqi@1 2268 break;
aoqi@1 2269
aoqi@1 2270 case lir_cond_greaterEqual: {
aoqi@1 2271 #ifdef _LP64
aoqi@1 2272 __ slt(AT, opr1_lo, opr2_lo);
aoqi@1 2273 __ beq_far(AT, R0, *op->label());
aoqi@1 2274 __ delayed()->nop();
aoqi@1 2275 #else
aoqi@1 2276 Label L;
aoqi@1 2277
aoqi@1 2278 // if hi less then fail
aoqi@1 2279 __ slt(AT, opr1_hi, opr2_hi);
aoqi@1 2280 __ bne_far(AT, R0, L);
aoqi@1 2281 __ delayed()->nop();
aoqi@1 2282
aoqi@1 2283 // if hi great then jump
aoqi@1 2284 if(op->label()==NULL)
aoqi@1 2285 __ bne(opr2_hi, opr1_hi, *op->label());//by liaobin6
aoqi@1 2286 else
aoqi@1 2287 __ bne_far(opr2_hi, opr1_hi, *op->label());//by liaobin6
aoqi@1 2288 __ delayed();
aoqi@1 2289
aoqi@1 2290 // now just comp lo as unsigned
aoqi@1 2291 __ sltu(AT, opr1_lo, opr2_lo);
aoqi@1 2292 __ beq(AT, R0, *op->label());
aoqi@1 2293 __ delayed()->nop();
aoqi@1 2294
aoqi@1 2295 __ bind(L);
aoqi@1 2296 #endif
aoqi@1 2297 }
aoqi@1 2298 break;
aoqi@1 2299
aoqi@1 2300 case lir_cond_aboveEqual: {
aoqi@1 2301 #ifdef _LP64
aoqi@1 2302 __ sltu(AT, opr1_lo, opr2_lo);
aoqi@1 2303 __ beq_far(AT, R0, *op->label());
aoqi@1 2304 __ delayed()->nop();
aoqi@1 2305 #else
aoqi@1 2306 Label L;
aoqi@1 2307
aoqi@1 2308 // if hi less then fail
aoqi@1 2309 __ sltu(AT, opr1_hi, opr2_hi);
aoqi@1 2310 __ bne(AT, R0, L);
aoqi@1 2311 __ delayed()->nop();
aoqi@1 2312
aoqi@1 2313 // if hi great then jump
aoqi@1 2314 if(op->label()==NULL)
aoqi@1 2315 __ bne(opr2_hi, opr1_hi, *op->label());//by liaobin7
aoqi@1 2316 else
aoqi@1 2317 __ bne_far(opr2_hi, opr1_hi, *op->label());//by liaobin7
aoqi@1 2318 __ delayed();
aoqi@1 2319
aoqi@1 2320 // now just comp lo as unsigned
aoqi@1 2321 __ sltu(AT, opr1_lo, opr2_lo);
aoqi@1 2322 __ beq(AT, R0, *op->label());
aoqi@1 2323 __ delayed()->nop();
aoqi@1 2324
aoqi@1 2325 __ bind(L);
aoqi@1 2326 #endif
aoqi@1 2327 }
aoqi@1 2328 break;
aoqi@1 2329
aoqi@1 2330 case lir_cond_greater: {
aoqi@1 2331 #ifdef _LP64
aoqi@1 2332 __ slt(AT, opr2_lo, opr1_lo);
aoqi@1 2333 __ bne_far(AT, R0, *op->label());
aoqi@1 2334 __ delayed()->nop();
aoqi@1 2335 #else
aoqi@1 2336 Label L;
aoqi@1 2337
aoqi@1 2338 // if hi great then jump
aoqi@1 2339 __ slt(AT, opr2_hi, opr1_hi);
aoqi@1 2340 __ bne(AT, R0, *op->label());
aoqi@1 2341 __ delayed()->nop();
aoqi@1 2342
aoqi@1 2343 // if hi less then fail
aoqi@1 2344 __ bne(opr2_hi, opr1_hi, L);
aoqi@1 2345 __ delayed();
aoqi@1 2346
aoqi@1 2347 // now just comp lo as unsigned
aoqi@1 2348 __ sltu(AT, opr2_lo, opr1_lo);
aoqi@1 2349 __ bne(AT, R0, *op->label());
aoqi@1 2350 __ delayed()->nop();
aoqi@1 2351
aoqi@1 2352 __ bind(L);
aoqi@1 2353 #endif
aoqi@1 2354 }
aoqi@1 2355 break;
aoqi@1 2356
aoqi@1 2357 default: ShouldNotReachHere();
aoqi@1 2358 }
aoqi@1 2359
aoqi@1 2360 } else if(opr2->is_constant()) {
aoqi@1 2361 jlong lv = opr2->as_jlong();
aoqi@1 2362 #ifndef _LP64
aoqi@1 2363 jint iv_lo = (jint)lv;
aoqi@1 2364 jint iv_hi = (jint)(lv>>32);
aoqi@1 2365 bool is_zero = (lv==0);
aoqi@1 2366 #endif
aoqi@1 2367
aoqi@1 2368 switch (condition) {
aoqi@1 2369 case lir_cond_equal:
aoqi@1 2370 #ifdef _LP64
aoqi@1 2371 __ li(T8, lv);
aoqi@1 2372 __ beq(opr1_lo, T8, *op->label());
aoqi@1 2373 __ delayed()->nop();
aoqi@1 2374 #else
aoqi@1 2375 if (is_zero) {
aoqi@1 2376 __ orr(AT, opr1_lo, opr1_hi);
aoqi@1 2377 __ beq(AT, R0, *op->label());
aoqi@1 2378 __ delayed()->nop();
aoqi@1 2379 } else {
aoqi@1 2380 Label L;
aoqi@1 2381 __ move(T8, iv_lo);
aoqi@1 2382 __ bne(opr1_lo, T8, L);
aoqi@1 2383 __ delayed();
aoqi@1 2384 __ move(T8, iv_hi);
aoqi@1 2385 __ beq(opr1_hi, T8, *op->label());
aoqi@1 2386 __ delayed()->nop();
aoqi@1 2387 __ bind(L);
aoqi@1 2388 }
aoqi@1 2389 #endif
aoqi@1 2390 break;
aoqi@1 2391
aoqi@1 2392 case lir_cond_notEqual:
aoqi@1 2393 #ifdef _LP64
aoqi@1 2394 __ li(T8, lv);
aoqi@1 2395 __ bne(opr1_lo, T8, *op->label());
aoqi@1 2396 __ delayed()->nop();
aoqi@1 2397 #else
aoqi@1 2398 if (is_zero) {
aoqi@1 2399 __ orr(AT, opr1_lo, opr1_hi);
aoqi@1 2400 __ bne(AT, R0, *op->label());
aoqi@1 2401 __ delayed()->nop();
aoqi@1 2402 } else {
aoqi@1 2403 __ move(T8, iv_lo);
aoqi@1 2404 __ bne(opr1_lo, T8, *op->label());
aoqi@1 2405 __ delayed();
aoqi@1 2406 __ move(T8, iv_hi);
aoqi@1 2407 __ bne(opr1_hi, T8, *op->label());
aoqi@1 2408 __ delayed()->nop();
aoqi@1 2409 }
aoqi@1 2410 #endif
aoqi@1 2411 break;
aoqi@1 2412
aoqi@1 2413 case lir_cond_less:
aoqi@1 2414 #ifdef _LP64
aoqi@1 2415 __ li(T8, lv);
aoqi@1 2416 __ slt(AT, opr1_lo, T8);
aoqi@1 2417 __ bne_far(AT, R0, *op->label());
aoqi@1 2418 __ delayed()->nop();
aoqi@1 2419 #else
aoqi@1 2420 if (is_zero) {
aoqi@1 2421 __ bltz(opr1_hi, *op->label());
aoqi@1 2422 __ bltz(opr1_lo, *op->label());
aoqi@1 2423 __ delayed()->nop();
aoqi@1 2424 } else {
aoqi@1 2425 Label L;
aoqi@1 2426
aoqi@1 2427 // if hi less then jump
aoqi@1 2428 __ move(T8, iv_hi);
aoqi@1 2429 __ slt(AT, opr1_hi, T8);
aoqi@1 2430 __ bne_far(AT, R0, *op->label());
aoqi@1 2431 __ delayed()->nop();
aoqi@1 2432
aoqi@1 2433 // if hi great then fail
aoqi@1 2434 __ bne(opr1_hi, T8, L);
aoqi@1 2435 __ delayed();
aoqi@1 2436
aoqi@1 2437 // now just comp lo as unsigned
aoqi@1 2438 if (Assembler::is_simm16(iv_lo)) {
aoqi@1 2439 __ sltiu(AT, opr1_lo, iv_lo);
aoqi@1 2440 } else {
aoqi@1 2441 __ move(T8, iv_lo);
aoqi@1 2442 __ sltu(AT, opr1_lo, T8);
aoqi@1 2443 }
aoqi@1 2444 __ bne(AT, R0, *op->label());
aoqi@1 2445 __ delayed()->nop();
aoqi@1 2446
aoqi@1 2447 __ bind(L);
aoqi@1 2448 }
aoqi@1 2449 #endif
aoqi@1 2450 break;
aoqi@1 2451
aoqi@1 2452 case lir_cond_lessEqual:
aoqi@1 2453 #ifdef _LP64
aoqi@1 2454 __ li(T8, lv);
aoqi@1 2455 __ slt(AT, T8, opr1_lo);
aoqi@1 2456 __ beq(AT, R0, *op->label());
aoqi@1 2457 __ delayed()->nop();
aoqi@1 2458 #else
aoqi@1 2459 if (is_zero) {
aoqi@1 2460 __ bltz(opr1_hi, *op->label());
aoqi@1 2461 __ delayed()->nop();
aoqi@1 2462 __ orr(AT, opr1_hi, opr1_lo);
aoqi@1 2463 __ beq(AT, R0, *op->label());
aoqi@1 2464 __ delayed();
aoqi@1 2465 } else {
aoqi@1 2466 Label L;
aoqi@1 2467
aoqi@1 2468 // if hi great then fail
aoqi@1 2469 __ move(T8, iv_hi);
aoqi@1 2470 __ slt(AT, T8, opr1_hi);
aoqi@1 2471 __ bne(AT, R0, L);
aoqi@1 2472 __ delayed()->nop();
aoqi@1 2473
aoqi@1 2474 // if hi less then jump
aoqi@1 2475 __ bne(T8, opr1_hi, *op->label());
aoqi@1 2476 __ delayed();
aoqi@1 2477
aoqi@1 2478 // now just comp lo as unsigned
aoqi@1 2479 __ move(T8, iv_lo);
aoqi@1 2480 __ sltu(AT, T8, opr1_lo);
aoqi@1 2481 __ beq(AT, R0, *op->label());
aoqi@1 2482 __ delayed()->nop();
aoqi@1 2483
aoqi@1 2484 __ bind(L);
aoqi@1 2485 }
aoqi@1 2486 #endif
aoqi@1 2487 break;
aoqi@1 2488
aoqi@1 2489 case lir_cond_belowEqual:
aoqi@1 2490 #ifdef _LP64
aoqi@1 2491 __ li(T8, lv);
aoqi@1 2492 __ sltu(AT, T8, opr1_lo);
aoqi@1 2493 __ beq(AT, R0, *op->label());
aoqi@1 2494 __ delayed()->nop();
aoqi@1 2495 #else
aoqi@1 2496 if (is_zero) {
aoqi@1 2497 __ orr(AT, opr1_hi, opr1_lo);
aoqi@1 2498 __ beq(AT, R0, *op->label());
aoqi@1 2499 __ delayed()->nop();
aoqi@1 2500 } else {
aoqi@1 2501 Label L;
aoqi@1 2502
aoqi@1 2503 // if hi great then fail
aoqi@1 2504 __ move(T8, iv_hi);
aoqi@1 2505 __ sltu(AT, T8, opr1_hi);
aoqi@1 2506 __ bne(AT, R0, L);
aoqi@1 2507 __ delayed()->nop();
aoqi@1 2508
aoqi@1 2509 // if hi less then jump
aoqi@1 2510 __ bne(T8, opr1_hi, *op->label());
aoqi@1 2511 __ delayed();
aoqi@1 2512
aoqi@1 2513 // now just comp lo as unsigned
aoqi@1 2514 __ move(T8, iv_lo);
aoqi@1 2515 __ sltu(AT, T8, opr1_lo);
aoqi@1 2516 __ beq(AT, R0, *op->label());
aoqi@1 2517 __ delayed()->nop();
aoqi@1 2518
aoqi@1 2519 __ bind(L);
aoqi@1 2520 }
aoqi@1 2521 #endif
aoqi@1 2522 break;
aoqi@1 2523
aoqi@1 2524 case lir_cond_greaterEqual:
aoqi@1 2525 #ifdef _LP64
aoqi@1 2526 __ li(T8, lv);
aoqi@1 2527 __ slt(AT, opr1_lo, T8);
aoqi@1 2528 __ beq(AT, R0, *op->label());
aoqi@1 2529 __ delayed()->nop();
aoqi@1 2530 #else
aoqi@1 2531 if (is_zero) {
aoqi@1 2532 __ bgez(opr1_hi, *op->label());
aoqi@1 2533 __ delayed()->nop();
aoqi@1 2534 } else {
aoqi@1 2535 Label L;
aoqi@1 2536
aoqi@1 2537 // if hi less then fail
aoqi@1 2538 __ move(T8, iv_hi);
aoqi@1 2539 __ slt(AT, opr1_hi, T8);
aoqi@1 2540 __ bne(AT, R0, L);
aoqi@1 2541 __ delayed()->nop();
aoqi@1 2542
aoqi@1 2543 // if hi great then jump
aoqi@1 2544 __ bne(T8, opr1_hi, *op->label());
aoqi@1 2545 __ delayed();
aoqi@1 2546
aoqi@1 2547 // now just comp lo as unsigned
aoqi@1 2548 if (Assembler::is_simm16(iv_lo)) {
aoqi@1 2549 __ sltiu(AT, opr1_lo, iv_lo);
aoqi@1 2550 } else {
aoqi@1 2551 __ move(T8, iv_lo);
aoqi@1 2552 __ sltu(AT, opr1_lo, T8);
aoqi@1 2553 }
aoqi@1 2554 __ beq(AT, R0, *op->label());
aoqi@1 2555 __ delayed()->nop();
aoqi@1 2556
aoqi@1 2557 __ bind(L);
aoqi@1 2558 }
aoqi@1 2559 #endif
aoqi@1 2560 break;
aoqi@1 2561
aoqi@1 2562 case lir_cond_aboveEqual:
aoqi@1 2563 #ifdef _LP64
aoqi@1 2564 __ li(T8, lv);
aoqi@1 2565 __ sltu(AT, opr1_lo, T8);
aoqi@1 2566 __ beq(AT, R0, *op->label());
aoqi@1 2567 __ delayed()->nop();
aoqi@1 2568 #else
aoqi@1 2569 if (is_zero) {
aoqi@1 2570 if(op->label()==NULL) //by liaob2
aoqi@1 2571 __ b(*op->label());
aoqi@1 2572 else
aoqi@1 2573 __ b_far(*op->label());
aoqi@1 2574 __ delayed()->nop();
aoqi@1 2575 } else {
aoqi@1 2576 Label L;
aoqi@1 2577
aoqi@1 2578 // if hi less then fail
aoqi@1 2579 __ move(T8, iv_hi);
aoqi@1 2580 __ sltu(AT, opr1_hi, T8);
aoqi@1 2581 __ bne(AT, R0, L);
aoqi@1 2582 __ delayed()->nop();
aoqi@1 2583
aoqi@1 2584 // if hi great then jump
aoqi@1 2585 __ bne(T8, opr1_hi, *op->label());
aoqi@1 2586 __ delayed();
aoqi@1 2587
aoqi@1 2588 // now just comp lo as unsigned
aoqi@1 2589 if (Assembler::is_simm16(iv_lo)) {
aoqi@1 2590 __ sltiu(AT, opr1_lo, iv_lo);
aoqi@1 2591 } else {
aoqi@1 2592 __ move(T8, iv_lo);
aoqi@1 2593 __ sltu(AT, opr1_lo, T8);
aoqi@1 2594 }
aoqi@1 2595 __ beq(AT, R0, *op->label());
aoqi@1 2596 __ delayed()->nop();
aoqi@1 2597
aoqi@1 2598 __ bind(L);
aoqi@1 2599 }
aoqi@1 2600 #endif
aoqi@1 2601 break;
aoqi@1 2602
aoqi@1 2603 case lir_cond_greater:
aoqi@1 2604 #ifdef _LP64
aoqi@1 2605 __ li(T8, lv);
aoqi@1 2606 __ slt(AT, T8, opr1_lo);
aoqi@1 2607 __ bne_far(AT, R0, *op->label());
aoqi@1 2608 __ delayed()->nop();
aoqi@1 2609 #else
aoqi@1 2610 if (is_zero) {
aoqi@1 2611 Label L;
aoqi@1 2612 __ bgtz(opr1_hi, *op->label());
aoqi@1 2613 __ delayed()->nop();
aoqi@1 2614 __ bne(opr1_hi, R0, L);
aoqi@1 2615 __ delayed()->nop();
aoqi@1 2616 __ bne(opr1_lo, R0, *op->label());
aoqi@1 2617 __ delayed()->nop();
aoqi@1 2618 __ bind(L);
aoqi@1 2619 } else {
aoqi@1 2620 Label L;
aoqi@1 2621
aoqi@1 2622 // if hi great then jump
aoqi@1 2623 __ move(T8, iv_hi);
aoqi@1 2624 __ slt(AT, T8, opr1_hi);
aoqi@1 2625 __ bne(AT, R0, *op->label());
aoqi@1 2626 __ delayed()->nop();
aoqi@1 2627
aoqi@1 2628 // if hi less then fail
aoqi@1 2629 __ bne(T8, opr1_hi, L);
aoqi@1 2630 __ delayed();
aoqi@1 2631
aoqi@1 2632 // now just comp lo as unsigned
aoqi@1 2633 __ move(T8, iv_lo);
aoqi@1 2634 __ sltu(AT, T8, opr1_lo);
aoqi@1 2635 __ bne(AT, R0, *op->label());
aoqi@1 2636 __ delayed()->nop();
aoqi@1 2637
aoqi@1 2638 __ bind(L);
aoqi@1 2639 }
aoqi@1 2640 #endif
aoqi@1 2641 break;
aoqi@1 2642
aoqi@1 2643 default:
aoqi@1 2644 ShouldNotReachHere();
aoqi@1 2645 }
aoqi@1 2646 } else {
aoqi@1 2647 Unimplemented();
aoqi@1 2648 }
aoqi@1 2649 } else if (opr1->is_single_fpu()) {
aoqi@1 2650 #ifdef OPT_RANGECHECK
aoqi@1 2651 assert(!op->check(), "just check");
aoqi@1 2652 #endif
aoqi@1 2653 assert(opr2->is_single_fpu(), "change the code");
aoqi@1 2654
aoqi@1 2655 FloatRegister reg_op1 = opr1->as_float_reg();
aoqi@1 2656 FloatRegister reg_op2 = opr2->as_float_reg();
aoqi@1 2657 // bool un_ls
aoqi@1 2658 bool un_jump = (op->ublock()->label()==op->label());
aoqi@1 2659
aoqi@1 2660 Label& L = *op->label();
aoqi@1 2661
aoqi@1 2662 switch (condition) {
aoqi@1 2663 case lir_cond_equal:
aoqi@1 2664 if (un_jump)
aoqi@1 2665 __ c_ueq_s(reg_op1, reg_op2);
aoqi@1 2666 else
aoqi@1 2667 __ c_eq_s(reg_op1, reg_op2);
aoqi@1 2668 __ bc1t(L);
aoqi@1 2669
aoqi@1 2670 break;
aoqi@1 2671
aoqi@1 2672 case lir_cond_notEqual:
aoqi@1 2673 if (un_jump)
aoqi@1 2674 __ c_eq_s(reg_op1, reg_op2);
aoqi@1 2675 else
aoqi@1 2676 __ c_ueq_s(reg_op1, reg_op2);
aoqi@1 2677 __ bc1f(L);
aoqi@1 2678
aoqi@1 2679 break;
aoqi@1 2680
aoqi@1 2681 case lir_cond_less:
aoqi@1 2682 if (un_jump)
aoqi@1 2683 __ c_ult_s(reg_op1, reg_op2);
aoqi@1 2684 else
aoqi@1 2685 __ c_olt_s(reg_op1, reg_op2);
aoqi@1 2686 __ bc1t(L);
aoqi@1 2687
aoqi@1 2688 break;
aoqi@1 2689
aoqi@1 2690 case lir_cond_lessEqual:
aoqi@1 2691 case lir_cond_belowEqual:
aoqi@1 2692 if (un_jump)
aoqi@1 2693 __ c_ule_s(reg_op1, reg_op2);
aoqi@1 2694 else
aoqi@1 2695 __ c_ole_s(reg_op1, reg_op2);
aoqi@1 2696 __ bc1t(L);
aoqi@1 2697
aoqi@1 2698 break;
aoqi@1 2699
aoqi@1 2700 case lir_cond_greaterEqual:
aoqi@1 2701 case lir_cond_aboveEqual:
aoqi@1 2702 if (un_jump)
aoqi@1 2703 __ c_olt_s(reg_op1, reg_op2);
aoqi@1 2704 else
aoqi@1 2705 __ c_ult_s(reg_op1, reg_op2);
aoqi@1 2706 __ bc1f(L);
aoqi@1 2707
aoqi@1 2708 break;
aoqi@1 2709
aoqi@1 2710 case lir_cond_greater:
aoqi@1 2711 if (un_jump)
aoqi@1 2712 __ c_ole_s(reg_op1, reg_op2);
aoqi@1 2713 else
aoqi@1 2714 __ c_ule_s(reg_op1, reg_op2);
aoqi@1 2715 __ bc1f(L);
aoqi@1 2716
aoqi@1 2717 break;
aoqi@1 2718
aoqi@1 2719 default:
aoqi@1 2720 ShouldNotReachHere();
aoqi@1 2721 }
aoqi@1 2722 __ delayed()->nop();
aoqi@1 2723 } else if (opr1->is_double_fpu()) {
aoqi@1 2724 #ifdef OPT_RANGECHECK
aoqi@1 2725 assert(!op->check(), "just check");
aoqi@1 2726 #endif
aoqi@1 2727 assert(opr2->is_double_fpu(), "change the code");
aoqi@1 2728
aoqi@1 2729 FloatRegister reg_op1 = opr1->as_double_reg();
aoqi@1 2730 FloatRegister reg_op2 = opr2->as_double_reg();
aoqi@1 2731 bool un_jump = (op->ublock()->label()==op->label());
aoqi@1 2732 Label& L = *op->label();
aoqi@1 2733
aoqi@1 2734 switch (condition) {
aoqi@1 2735 case lir_cond_equal:
aoqi@1 2736 if (un_jump)
aoqi@1 2737 __ c_ueq_d(reg_op1, reg_op2);
aoqi@1 2738 else
aoqi@1 2739 __ c_eq_d(reg_op1, reg_op2);
aoqi@1 2740 __ bc1t(L);
aoqi@1 2741
aoqi@1 2742 break;
aoqi@1 2743
aoqi@1 2744 case lir_cond_notEqual:
aoqi@1 2745 if (un_jump)
aoqi@1 2746 __ c_eq_d(reg_op1, reg_op2);
aoqi@1 2747 else
aoqi@1 2748 __ c_ueq_d(reg_op1, reg_op2);
aoqi@1 2749 __ bc1f(L);
aoqi@1 2750
aoqi@1 2751 break;
aoqi@1 2752
aoqi@1 2753 case lir_cond_less:
aoqi@1 2754 if (un_jump)
aoqi@1 2755 __ c_ult_d(reg_op1, reg_op2);
aoqi@1 2756 else
aoqi@1 2757 __ c_olt_d(reg_op1, reg_op2);
aoqi@1 2758 __ bc1t(L);
aoqi@1 2759
aoqi@1 2760 break;
aoqi@1 2761
aoqi@1 2762 case lir_cond_lessEqual:
aoqi@1 2763 case lir_cond_belowEqual:
aoqi@1 2764 if (un_jump)
aoqi@1 2765 __ c_ule_d(reg_op1, reg_op2);
aoqi@1 2766 else
aoqi@1 2767 __ c_ole_d(reg_op1, reg_op2);
aoqi@1 2768 __ bc1t(L);
aoqi@1 2769
aoqi@1 2770 break;
aoqi@1 2771
aoqi@1 2772 case lir_cond_greaterEqual:
aoqi@1 2773 case lir_cond_aboveEqual:
aoqi@1 2774 if (un_jump)
aoqi@1 2775 __ c_olt_d(reg_op1, reg_op2);
aoqi@1 2776 else
aoqi@1 2777 __ c_ult_d(reg_op1, reg_op2);
aoqi@1 2778 __ bc1f(L);
aoqi@1 2779
aoqi@1 2780 break;
aoqi@1 2781
aoqi@1 2782 case lir_cond_greater:
aoqi@1 2783 if (un_jump)
aoqi@1 2784 __ c_ole_d(reg_op1, reg_op2);
aoqi@1 2785 else
aoqi@1 2786 __ c_ule_d(reg_op1, reg_op2);
aoqi@1 2787 __ bc1f(L);
aoqi@1 2788
aoqi@1 2789 break;
aoqi@1 2790
aoqi@1 2791 default:
aoqi@1 2792 ShouldNotReachHere();
aoqi@1 2793 }
aoqi@1 2794 __ delayed()->nop();
aoqi@1 2795 } else {
aoqi@1 2796 Unimplemented();
aoqi@1 2797 }
aoqi@1 2798 }
aoqi@1 2799
aoqi@1 2800
aoqi@1 2801 void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) {
aoqi@1 2802 LIR_Opr value = op->in_opr();
aoqi@1 2803 LIR_Opr src = op->in_opr();
aoqi@1 2804 LIR_Opr dest = op->result_opr();
aoqi@1 2805 Bytecodes::Code code = op->bytecode();
aoqi@1 2806
aoqi@1 2807 switch (code) {
aoqi@1 2808 case Bytecodes::_i2l:
aoqi@1 2809 move_regs(src->as_register(), dest->as_register_lo());
aoqi@1 2810 NOT_LP64(__ sra (dest->as_register_hi(), dest->as_register_lo(), 31));
aoqi@1 2811 break;
aoqi@1 2812
aoqi@1 2813 case Bytecodes::_l2i:
aoqi@1 2814 #ifndef _LP64
aoqi@1 2815 move_regs (src->as_register_lo(), dest->as_register());
aoqi@1 2816 #else
aoqi@1 2817 __ dsll32(dest->as_register(), src->as_register_lo(), 0);
aoqi@1 2818 __ dsra32(dest->as_register(), dest->as_register(), 0);
aoqi@1 2819 #endif
aoqi@1 2820 break;
aoqi@1 2821
aoqi@1 2822 case Bytecodes::_i2b:
aoqi@1 2823 #ifndef _LP64
aoqi@1 2824 move_regs (src->as_register(), dest->as_register());
aoqi@1 2825 __ sign_extend_byte(dest->as_register());
aoqi@1 2826 #else
aoqi@1 2827 __ dsll32(dest->as_register(), src->as_register(), 24);
aoqi@1 2828 __ dsra32(dest->as_register(), dest->as_register(), 24);
aoqi@1 2829 #endif
aoqi@1 2830 break;
aoqi@1 2831
aoqi@1 2832 case Bytecodes::_i2c:
aoqi@1 2833 __ andi(dest->as_register(), src->as_register(), 0xFFFF);
aoqi@1 2834 break;
aoqi@1 2835
aoqi@1 2836 case Bytecodes::_i2s:
aoqi@1 2837 #ifndef _LP64
aoqi@1 2838 move_regs (src->as_register(), dest->as_register());
aoqi@1 2839 __ sign_extend_short(dest->as_register());
aoqi@1 2840 #else
aoqi@1 2841 __ dsll32(dest->as_register(), src->as_register(), 16);
aoqi@1 2842 __ dsra32(dest->as_register(), dest->as_register(), 16);
aoqi@1 2843 #endif
aoqi@1 2844 break;
aoqi@1 2845
aoqi@1 2846 case Bytecodes::_f2d:
aoqi@1 2847 __ cvt_d_s(dest->as_double_reg(), src->as_float_reg());
aoqi@1 2848 break;
aoqi@1 2849
aoqi@1 2850 case Bytecodes::_d2f:
aoqi@1 2851 __ cvt_s_d(dest->as_float_reg(), src->as_double_reg());
aoqi@1 2852 break;
aoqi@1 2853 case Bytecodes::_i2f: {
aoqi@1 2854 FloatRegister df = dest->as_float_reg();
aoqi@1 2855 if(src->is_single_cpu()) {
aoqi@1 2856 __ mtc1(src->as_register(), df);
aoqi@1 2857 __ cvt_s_w(df, df);
aoqi@1 2858 } else if (src->is_stack()) {
aoqi@1 2859 Address src_addr = src->is_single_stack()
aoqi@1 2860 ? frame_map()->address_for_slot(src->single_stack_ix())
aoqi@1 2861 : frame_map()->address_for_slot(src->double_stack_ix());
aoqi@1 2862 __ lw(AT, src_addr);
aoqi@1 2863 __ mtc1(AT, df);
aoqi@1 2864 __ cvt_s_w(df, df);
aoqi@1 2865 } else {
aoqi@1 2866 Unimplemented();
aoqi@1 2867 }
aoqi@1 2868 break;
aoqi@1 2869 }
aoqi@1 2870 case Bytecodes::_i2d: {
aoqi@1 2871 FloatRegister dd = dest->as_double_reg();
aoqi@1 2872 if (src->is_single_cpu()) {
aoqi@1 2873 __ mtc1(src->as_register(), dd);
aoqi@1 2874 __ cvt_d_w(dd, dd);
aoqi@1 2875 } else if (src->is_stack()) {
aoqi@1 2876 Address src_addr = src->is_single_stack()
aoqi@1 2877 ? frame_map()->address_for_slot(value->single_stack_ix())
aoqi@1 2878 : frame_map()->address_for_slot(value->double_stack_ix());
aoqi@1 2879 __ lw(AT, src_addr);
aoqi@1 2880 __ mtc1(AT, dd);
aoqi@1 2881 __ cvt_d_w(dd, dd);
aoqi@1 2882 } else {
aoqi@1 2883 Unimplemented();
aoqi@1 2884 }
aoqi@1 2885 break;
aoqi@1 2886 }
aoqi@1 2887 case Bytecodes::_f2i: {
aoqi@1 2888 FloatRegister fval = src->as_float_reg();
aoqi@1 2889 Register dreg = dest->as_register();
aoqi@1 2890
aoqi@1 2891 Label L;
aoqi@1 2892 __ c_un_s(fval, fval); //NaN?
aoqi@1 2893 __ bc1t(L);
aoqi@1 2894 __ delayed();
aoqi@1 2895 __ move(dreg, R0);
aoqi@1 2896
aoqi@1 2897 __ trunc_w_s(F30, fval);
aoqi@1 2898
aoqi@1 2899 /* Call SharedRuntime:f2i() to do valid convention */
aoqi@1 2900 __ cfc1(AT, 31);
aoqi@1 2901 __ li(T9, 0x10000);
aoqi@1 2902 __ andr(AT, AT, T9);
aoqi@1 2903 __ beq(AT, R0, L);
aoqi@1 2904 __ delayed()->mfc1(dreg, F30);
aoqi@1 2905
aoqi@1 2906 __ mov_s(F12, fval);
aoqi@1 2907 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1);
aoqi@1 2908 __ move(dreg, V0);
aoqi@1 2909 __ bind(L);
aoqi@1 2910 break;
aoqi@1 2911 }
aoqi@1 2912 case Bytecodes::_d2i: {
aoqi@1 2913 FloatRegister dval = src->as_double_reg();
aoqi@1 2914 Register dreg = dest->as_register();
aoqi@1 2915
aoqi@1 2916 Label L;
aoqi@1 2917 #ifndef _LP64
aoqi@1 2918 __ c_un_d(dval, dval); //NaN?
aoqi@1 2919 __ bc1t(L);
aoqi@1 2920 __ delayed();
aoqi@1 2921 __ move(dreg, R0);
aoqi@1 2922 #endif
aoqi@1 2923
aoqi@1 2924 __ trunc_w_d(F30, dval);
aoqi@1 2925 __ cfc1(AT, 31);
aoqi@1 2926 __ li(T9, 0x10000);
aoqi@1 2927 __ andr(AT, AT, T9);
aoqi@1 2928 __ beq(AT, R0, L);
aoqi@1 2929 __ delayed()->mfc1(dreg, F30);
aoqi@1 2930
aoqi@1 2931 __ mov_d(F12, dval);
aoqi@1 2932 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 1);
aoqi@1 2933 __ move(dreg, V0);
aoqi@1 2934 __ bind(L);
aoqi@1 2935 break;
aoqi@1 2936 }
aoqi@1 2937 case Bytecodes::_l2f: {
aoqi@1 2938 FloatRegister ldf = dest->as_float_reg();
aoqi@1 2939 if (src->is_double_cpu()) {
aoqi@1 2940 #ifndef _LP64
aoqi@1 2941 __ mtc1(src->as_register_lo(), ldf);
aoqi@1 2942 __ mtc1(src->as_register_hi(), ldf + 1);
aoqi@1 2943 __ cvt_s_l(ldf, ldf);
aoqi@1 2944 #else
aoqi@1 2945 __ dmtc1(src->as_register_lo(), ldf);
aoqi@1 2946 __ cvt_s_l(ldf, ldf);
aoqi@1 2947 #endif
aoqi@1 2948 } else if (src->is_double_stack()) {
aoqi@1 2949 Address src_addr=frame_map()->address_for_slot(value->double_stack_ix());
aoqi@1 2950 #ifndef _LP64
aoqi@1 2951 __ lw(AT, src_addr);
aoqi@1 2952 __ mtc1(AT, ldf);
aoqi@1 2953 __ lw(AT, src_addr.base(), src_addr.disp() + 4);
aoqi@1 2954 __ mtc1(AT, ldf + 1);
aoqi@1 2955 __ cvt_s_l(ldf, ldf);
aoqi@1 2956 #else
aoqi@1 2957 __ ld(AT, src_addr);
aoqi@1 2958 __ dmtc1(AT, ldf);
aoqi@1 2959 __ cvt_s_l(ldf, ldf);
aoqi@1 2960 #endif
aoqi@1 2961 } else {
aoqi@1 2962 Unimplemented();
aoqi@1 2963 }
aoqi@1 2964 break;
aoqi@1 2965 }
aoqi@1 2966 case Bytecodes::_l2d: {
aoqi@1 2967 FloatRegister ldd = dest->as_double_reg();
aoqi@1 2968 if (src->is_double_cpu()) {
aoqi@1 2969 #ifndef _LP64
aoqi@1 2970 __ mtc1(src->as_register_lo(), ldd);
aoqi@1 2971 __ mtc1(src->as_register_hi(), ldd + 1);
aoqi@1 2972 __ cvt_d_l(ldd, ldd);
aoqi@1 2973 #else
aoqi@1 2974 __ dmtc1(src->as_register_lo(), ldd);
aoqi@1 2975 __ cvt_d_l(ldd, ldd);
aoqi@1 2976 #endif
aoqi@1 2977 } else if (src->is_double_stack()) {
aoqi@1 2978 Address src_addr = frame_map()->address_for_slot(src->double_stack_ix());
aoqi@1 2979 #ifndef _LP64
aoqi@1 2980 __ lw(AT, src_addr);
aoqi@1 2981 __ mtc1(AT, ldd);
aoqi@1 2982 __ lw(AT, src_addr.base(), src_addr.disp() + 4);
aoqi@1 2983 __ mtc1(AT, ldd + 1);
aoqi@1 2984 __ cvt_d_l(ldd, ldd);
aoqi@1 2985 #else
aoqi@1 2986 __ ld(AT, src_addr);
aoqi@1 2987 __ dmtc1(AT, ldd);
aoqi@1 2988 __ cvt_d_l(ldd, ldd);
aoqi@1 2989 #endif
aoqi@1 2990 } else {
aoqi@1 2991 Unimplemented();
aoqi@1 2992 }
aoqi@1 2993 break;
aoqi@1 2994 }
aoqi@1 2995
aoqi@1 2996 case Bytecodes::_f2l: {
aoqi@1 2997 FloatRegister fval = src->as_float_reg();
aoqi@1 2998 Register dlo = dest->as_register_lo();
aoqi@1 2999 Register dhi = dest->as_register_hi();
aoqi@1 3000
aoqi@1 3001 Label L;
aoqi@1 3002 __ move(dhi, R0);
aoqi@1 3003 __ c_un_s(fval, fval); //NaN?
aoqi@1 3004 __ bc1t(L);
aoqi@1 3005 __ delayed();
aoqi@1 3006 __ move(dlo, R0);
aoqi@1 3007
aoqi@1 3008 __ trunc_l_s(F30, fval);
aoqi@1 3009 #ifdef _LP64
aoqi@1 3010 __ cfc1(AT, 31);
aoqi@1 3011 __ li(T9, 0x10000);
aoqi@1 3012 __ andr(AT, AT, T9);
aoqi@1 3013 __ beq(AT, R0, L);
aoqi@1 3014 __ delayed()->dmfc1(dlo, F30);
aoqi@1 3015
aoqi@1 3016 __ mov_s(F12, fval);
aoqi@1 3017 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1);
aoqi@1 3018 __ move(dlo, V0);
aoqi@1 3019 #else
aoqi@1 3020 __ mfc1(dlo, F30);
aoqi@1 3021 #endif
aoqi@1 3022 NOT_LP64(__ mfc1(dhi, F31));
aoqi@1 3023 __ bind(L);
aoqi@1 3024 break;
aoqi@1 3025 }
aoqi@1 3026 case Bytecodes::_d2l: {
aoqi@1 3027 FloatRegister dval = src->as_double_reg();
aoqi@1 3028 Register dlo = dest->as_register_lo();
aoqi@1 3029 Register dhi = dest->as_register_hi();
aoqi@1 3030
aoqi@1 3031 Label L;
aoqi@1 3032 __ move(dhi, R0);
aoqi@1 3033 __ c_un_d(dval, dval); //NaN?
aoqi@1 3034 __ bc1t(L);
aoqi@1 3035 __ delayed();
aoqi@1 3036 __ move(dlo, R0);
aoqi@1 3037
aoqi@1 3038 __ trunc_l_d(F30, dval);
aoqi@1 3039 #ifdef _LP64
aoqi@1 3040 __ cfc1(AT, 31);
aoqi@1 3041 __ li(T9, 0x10000);
aoqi@1 3042 __ andr(AT, AT, T9);
aoqi@1 3043 __ beq(AT, R0, L);
aoqi@1 3044 __ delayed()->dmfc1(dlo, F30);
aoqi@1 3045
aoqi@1 3046 __ mov_d(F12, dval);
aoqi@1 3047 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 1);
aoqi@1 3048 __ move(dlo, V0);
aoqi@1 3049 #else
aoqi@1 3050 __ mfc1(dlo, F30);
aoqi@1 3051 __ mfc1(dhi, F31);
aoqi@1 3052 #endif
aoqi@1 3053 __ bind(L);
aoqi@1 3054 break;
aoqi@1 3055 }
aoqi@1 3056
aoqi@1 3057 default: ShouldNotReachHere();
aoqi@1 3058 }
aoqi@1 3059 }
aoqi@1 3060
aoqi@1 3061 void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) {
aoqi@1 3062 if (op->init_check()) {
aoqi@1 3063 add_debug_info_for_null_check_here(op->stub()->info());
aoqi@1 3064 __ lw(AT,Address(op->klass()->as_register(),
aoqi@1 3065 InstanceKlass::init_state_offset()));
aoqi@1 3066 __ addi(AT, AT, -InstanceKlass::fully_initialized);
aoqi@1 3067 __ bne_far(AT, R0,*op->stub()->entry());
aoqi@1 3068 __ delayed()->nop();
aoqi@1 3069 }
aoqi@1 3070 __ allocate_object(
aoqi@1 3071 op->obj()->as_register(),
aoqi@1 3072 op->tmp1()->as_register(),
aoqi@1 3073 op->tmp2()->as_register(),
aoqi@1 3074 op->header_size(),
aoqi@1 3075 op->object_size(),
aoqi@1 3076 op->klass()->as_register(),
aoqi@1 3077 *op->stub()->entry());
aoqi@1 3078
aoqi@1 3079 __ bind(*op->stub()->continuation());
aoqi@1 3080 }
aoqi@1 3081
aoqi@1 3082 void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) {
aoqi@1 3083 if (UseSlowPath ||
aoqi@1 3084 (!UseFastNewObjectArray && (op->type() == T_OBJECT || op->type() == T_ARRAY)) ||
aoqi@1 3085 (!UseFastNewTypeArray && (op->type() != T_OBJECT && op->type() != T_ARRAY))) {
aoqi@1 3086 __ b_far(*op->stub()->entry());
aoqi@1 3087 __ delayed()->nop();
aoqi@1 3088 } else {
aoqi@1 3089 Register len = op->len()->as_register();
aoqi@1 3090 Register tmp1 = op->tmp1()->as_register();
aoqi@1 3091 Register tmp2 = op->tmp2()->as_register();
aoqi@1 3092 Register tmp3 = op->tmp3()->as_register();
aoqi@1 3093 __ allocate_array(op->obj()->as_register(),
aoqi@1 3094 len,
aoqi@1 3095 tmp1,
aoqi@1 3096 tmp2,
aoqi@1 3097 tmp3,
aoqi@1 3098 arrayOopDesc::header_size(op->type()),
aoqi@1 3099 array_element_size(op->type()),
aoqi@1 3100 op->klass()->as_register(),
aoqi@1 3101 *op->stub()->entry());
aoqi@1 3102 }
aoqi@1 3103 __ bind(*op->stub()->continuation());
aoqi@1 3104 }
aoqi@1 3105
aoqi@1 3106
aoqi@1 3107
aoqi@1 3108 void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
aoqi@1 3109 LIR_Code code = op->code();
aoqi@1 3110 // if (code == lir_store_check) {
aoqi@1 3111 Register value = op->object()->as_register();
aoqi@1 3112 Register array = op->array()->as_register();
aoqi@1 3113 Register k_RInfo = op->tmp1()->as_register();
aoqi@1 3114 Register klass_RInfo = op->tmp2()->as_register();
aoqi@1 3115 Register tmp = op->tmp3()->as_register();
aoqi@1 3116
aoqi@1 3117 CodeStub* stub = op->stub();
aoqi@1 3118 //check if it needs to be profiled
aoqi@1 3119 ciMethodData* md;
aoqi@1 3120 ciProfileData* data;
aoqi@1 3121 if (op->should_profile()) {
aoqi@1 3122 ciMethod* method = op->profiled_method();
aoqi@1 3123 assert(method != NULL, "Should have method");
aoqi@1 3124 int bci = op->profiled_bci();
aoqi@1 3125 md = method->method_data_or_null();
aoqi@1 3126 assert(md != NULL, "Sanity");
aoqi@1 3127 data = md->bci_to_data(bci);
aoqi@1 3128 assert(data != NULL, "need data for type check");
aoqi@1 3129 assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
aoqi@1 3130 }
aoqi@1 3131 Label profile_cast_success, profile_cast_failure, done;
aoqi@1 3132 Label *success_target = op->should_profile() ? &profile_cast_success : &done;
aoqi@1 3133 Label *failure_target = op->should_profile() ? &profile_cast_failure : &done;
aoqi@1 3134 //__ cmpptr(value, (int32_t)NULL_WORD);
aoqi@1 3135 if(op->should_profile()) {
aoqi@1 3136 Label not_null;
aoqi@1 3137 __ bne(value, R0, not_null);
aoqi@1 3138 __ delayed()->nop();
aoqi@1 3139
aoqi@1 3140 // __ jcc(Assembler::notEqual, profile_done);
aoqi@1 3141 // __ bne(obj, R0, profile_done);
aoqi@1 3142 //__ delayed()->nop();
aoqi@1 3143
aoqi@1 3144 // Object is null; update methodDataOop
aoqi@1 3145 //ciMethodData* md = method->method_data();
aoqi@1 3146 //if (md == NULL) {
aoqi@1 3147 // bailout("out of memory building methodDataOop");
aoqi@1 3148 // return;
aoqi@1 3149 // }
aoqi@1 3150 // ciProfileData* data = md->bci_to_data(bci);
aoqi@1 3151 //assert(data != NULL, "need data for checkcast");
aoqi@1 3152 // assert(data->is_BitData(), "need BitData for checkcast");
aoqi@1 3153 Register mdo = klass_RInfo;
aoqi@1 3154 int oop_index = __ oop_recorder()->find_index(md->constant_encoding());
aoqi@1 3155 RelocationHolder rspec = oop_Relocation::spec(oop_index);
aoqi@1 3156 __ relocate(rspec);
aoqi@1 3157 #ifndef _LP64
aoqi@1 3158 //by_css
aoqi@1 3159 __ lui(mdo, Assembler::split_high((int)md->constant_encoding()));
aoqi@1 3160 __ addiu(mdo, mdo, Assembler::split_low((int)md->consant_encoding()));
aoqi@1 3161 #else
aoqi@1 3162 __ li48(mdo, (long)md->constant_encoding());
aoqi@1 3163 #endif
aoqi@1 3164
aoqi@1 3165 Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
aoqi@1 3166 //FIXME, it very ineffictive to replace orl with 3 mips instruction @jerome, 12/27,06
aoqi@1 3167 //__ orl(data_addr, BitData::null_flag_constant());
aoqi@1 3168 int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
aoqi@1 3169 __ lw(AT, data_addr);
aoqi@1 3170 __ ori(AT, AT, header_bits);
aoqi@1 3171 __ sw(AT,data_addr);
aoqi@1 3172 __ b(done);
aoqi@1 3173 __ delayed()->nop();
aoqi@1 3174 __ bind(not_null);
aoqi@1 3175 } else {
aoqi@1 3176 __ beq(value, R0, done);
aoqi@1 3177 __ delayed()->nop();
aoqi@1 3178 }
aoqi@1 3179 //__ verify_oop(obj);
aoqi@1 3180 add_debug_info_for_null_check_here(op->info_for_exception());
aoqi@1 3181 __ load_klass(k_RInfo, array);
aoqi@1 3182 __ load_klass(klass_RInfo, value);
aoqi@1 3183 // get instance klass (it's already uncompressed)
aoqi@1 3184 //__ movptr(k_RInfo, Address(k_RInfo, ObjArrayKlass::element_klass_offset()));
aoqi@1 3185 __ daddi (k_RInfo, k_RInfo, in_bytes(ObjArrayKlass::element_klass_offset()));
aoqi@1 3186 // perform the fast part of the checking logic
aoqi@1 3187 //__ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL);
aoqi@1 3188 // call out-of-line instance of __ check_klass_subtype_slow_path(...):
aoqi@1 3189 //1899 __ push(klass_RInfo);
aoqi@1 3190 //1900 __ push(k_RInfo);
aoqi@1 3191 //1901 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
aoqi@1 3192 //1902 __ pop(klass_RInfo);
aoqi@1 3193 //1903 __ pop(k_RInfo);
aoqi@1 3194 //1904 // result is a boolean
aoqi@1 3195 ///1905 __ cmpl(k_RInfo, 0);
aoqi@1 3196 //1906 __ jcc(Assembler::equal, *failure_target);
aoqi@1 3197 //1907 // fall through to the success case
aoqi@1 3198 //1908
aoqi@1 3199 //1909 if (op->should_profile()) {
aoqi@1 3200 //1910 Register mdo = klass_RInfo, recv = k_RInfo;
aoqi@1 3201 //1911 __ bind(profile_cast_success);
aoqi@1 3202 //1912 __ mov_metadata(mdo, md->constant_encoding());
aoqi@1 3203 //1913 __ load_klass(recv, value);
aoqi@1 3204 //1914 Label update_done;
aoqi@1 3205 //1915 type_profile_helper(mdo, md, data, recv, &done);
aoqi@1 3206 //1916 __ jmpb(done);
aoqi@1 3207 //1917
aoqi@1 3208 //1918 __ bind(profile_cast_failure);
aoqi@1 3209 //1919 __ mov_metadata(mdo, md->constant_encoding());
aoqi@1 3210 //1920 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
aoqi@1 3211 //1921 __ subptr(counter_addr, DataLayout::counter_increment);
aoqi@1 3212 //1922 __ jmp(*stub->entry());
aoqi@1 3213 //1923 }
aoqi@1 3214 //1925 __ bind(done);
aoqi@1 3215 //1926 } else
aoqi@1 3216 //1927 if (code == lir_checkcast) {
aoqi@1 3217 //1928 Register obj = op->object()->as_register();
aoqi@1 3218 //1929 Register dst = op->result_opr()->as_register();
aoqi@1 3219 //1930 Label success;
aoqi@1 3220 //1931 emit_typecheck_helper(op, &success, op->stub()->entry(), &success);
aoqi@1 3221 //1932 __ bind(success);
aoqi@1 3222 //1933 if (dst != obj) {
aoqi@1 3223 //1934 __ mov(dst, obj);
aoqi@1 3224 //1935 }
aoqi@1 3225 //1936 } else
aoqi@1 3226 //1937 if (code == lir_instanceof) {
aoqi@1 3227 //1938 Register obj = op->object()->as_register();
aoqi@1 3228 ///1939 Register dst = op->result_opr()->as_register();
aoqi@1 3229 //1940 Label success, failure, done;
aoqi@1 3230 //1941 emit_typecheck_helper(op, &success, &failure, &failure);
aoqi@1 3231 ///1942 __ bind(failure);
aoqi@1 3232 //1943 __ xorptr(dst, dst);
aoqi@1 3233 //1944 __ jmpb(done);
aoqi@1 3234 //1945 __ bind(success);
aoqi@1 3235 //1946 __ movptr(dst, 1);
aoqi@1 3236 //1947 __ bind(done);
aoqi@1 3237 //1948 } else {
aoqi@1 3238 //1949 ShouldNotReachHere();
aoqi@1 3239 //1950 }
aoqi@1 3240 //FIXME:wuhui.
aoqi@1 3241
aoqi@1 3242 }
aoqi@1 3243
aoqi@1 3244
aoqi@1 3245 void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) {
aoqi@1 3246 if (op->code() == lir_cas_long) {
aoqi@1 3247 #ifdef _LP64
aoqi@1 3248 Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo());
aoqi@1 3249 Register newval = (op->new_value()->is_single_cpu() ? op->new_value()->as_register() : op->new_value()->as_register_lo());
aoqi@1 3250 Register cmpval = (op->cmp_value()->is_single_cpu() ? op->cmp_value()->as_register() : op->cmp_value()->as_register_lo());
aoqi@1 3251 assert(newval != NULL, "new val must be register");
aoqi@1 3252 assert(cmpval != newval, "cmp and new values must be in different registers");
aoqi@1 3253 assert(cmpval != addr, "cmp and addr must be in different registers");
aoqi@1 3254 assert(newval != addr, "new value and addr must be in different registers");
aoqi@1 3255 if (os::is_MP()) {}
aoqi@1 3256 __ cmpxchg(newval, addr, cmpval); // 64-bit test-and-set
aoqi@1 3257 #else
aoqi@1 3258 Register addr = op->addr()->as_register();
aoqi@1 3259 if (os::is_MP()) {}
aoqi@1 3260 __ cmpxchg8(op->new_value()->as_register_lo(),
aoqi@1 3261 op->new_value()->as_register_hi(),
aoqi@1 3262 addr,
aoqi@1 3263 op->cmp_value()->as_register_lo(),
aoqi@1 3264 op->cmp_value()->as_register_hi())
aoqi@1 3265 #endif
aoqi@1 3266 } else if (op->code() == lir_cas_int || op->code() == lir_cas_obj) {
aoqi@1 3267 NOT_LP64(assert(op->addr()->is_single_cpu(), "must be single");)
aoqi@1 3268 Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo());
aoqi@1 3269 Register newval = op->new_value()->as_register();
aoqi@1 3270 Register cmpval = op->cmp_value()->as_register();
aoqi@1 3271 assert(newval != NULL, "new val must be register");
aoqi@1 3272 assert(cmpval != newval, "cmp and new values must be in different registers");
aoqi@1 3273 assert(cmpval != addr, "cmp and addr must be in different registers");
aoqi@1 3274 assert(newval != addr, "new value and addr must be in different registers");
aoqi@1 3275 if (op->code() == lir_cas_obj) {
aoqi@1 3276 #ifdef _LP64
aoqi@1 3277 if (UseCompressedOops) {
aoqi@1 3278 Register tmp_reg = S7;
aoqi@1 3279 __ push(cmpval);
aoqi@1 3280 __ encode_heap_oop(cmpval);
aoqi@1 3281 __ move(tmp_reg, newval);
aoqi@1 3282 __ encode_heap_oop(tmp_reg);
aoqi@1 3283 if (os::is_MP()) {}
aoqi@1 3284 __ cmpxchg32(tmp_reg, addr, cmpval); // 32-bit test-and-set
aoqi@1 3285 __ pop(cmpval);
aoqi@1 3286 } else
aoqi@1 3287 {
aoqi@1 3288 if (os::is_MP()) {}
aoqi@1 3289 __ cmpxchg(newval, addr, cmpval); // 64-bit test-and-set
aoqi@1 3290 }
aoqi@1 3291 } else
aoqi@1 3292 #endif
aoqi@1 3293 {
aoqi@1 3294 __ cmpxchg32(newval, addr, cmpval); // 32-bit test-and-set
aoqi@1 3295 }
aoqi@1 3296 } else {
aoqi@1 3297 Unimplemented();
aoqi@1 3298 }
aoqi@1 3299 }
aoqi@1 3300 #ifndef MIPS64
aoqi@1 3301 void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result) {
aoqi@1 3302 Unimplemented();
aoqi@1 3303 }
aoqi@1 3304 #endif
aoqi@1 3305 void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info,bool pop_fpu_stack) {
aoqi@1 3306 assert(info == NULL || ((code == lir_rem || code == lir_div || code == lir_sub) && right->is_double_cpu()), "info is only for ldiv/lrem");
aoqi@1 3307 if (left->is_single_cpu()) {
aoqi@1 3308 // left may not be equal to dest on mips.
aoqi@1 3309 //assert(left == dest, "left and dest must be equal");
aoqi@1 3310 Register lreg = left->as_register();
aoqi@1 3311
aoqi@1 3312 if (right->is_cpu_register()) {
aoqi@1 3313 // cpu register - cpu register
aoqi@1 3314 Register rreg, res;
aoqi@1 3315 if (right->is_single_cpu()) {
aoqi@1 3316 rreg = right->as_register();
aoqi@1 3317 #ifdef _LP64
aoqi@1 3318 if(dest->is_double_cpu())
aoqi@1 3319 res = dest->as_register_lo();
aoqi@1 3320 else
aoqi@1 3321 #endif
aoqi@1 3322 res = dest->as_register();
aoqi@1 3323 } else if (right->is_double_cpu()) {
aoqi@1 3324 assert(right->is_double_cpu(),"right must be long");
aoqi@1 3325 rreg = right->as_register_lo();
aoqi@1 3326 res = dest->as_register_lo();
aoqi@1 3327 } else {
aoqi@1 3328 ShouldNotReachHere();
aoqi@1 3329 }
aoqi@1 3330 switch (code) {
aoqi@1 3331 case lir_add:
aoqi@1 3332 #ifdef _LP64
aoqi@1 3333 if (dest->type() == T_INT)
aoqi@1 3334 __ addu32(res, lreg, rreg);
aoqi@1 3335 else
aoqi@1 3336 #endif
aoqi@1 3337 __ addu(res, lreg, rreg);
aoqi@1 3338 break;
aoqi@1 3339
aoqi@1 3340 case lir_mul:
aoqi@1 3341 #ifndef _LP64
aoqi@1 3342 //by aoqi
aoqi@1 3343 __ mult(lreg, rreg);
aoqi@1 3344 #else
aoqi@1 3345 __ dmult(lreg, rreg);
aoqi@1 3346 #endif
aoqi@1 3347 __ nop();
aoqi@1 3348 __ nop();
aoqi@1 3349 __ mflo(res);
aoqi@1 3350 #ifdef _LP64
aoqi@1 3351 /* Jin: if res < 0, it must be sign-extended. Otherwise it will be a 64-bit positive number.
aoqi@1 3352 *
aoqi@1 3353 * Example: java.net.URLClassLoader::string2int()
aoqi@1 3354 * a6: 0xcafebab
aoqi@1 3355 * s0: 16
aoqi@1 3356 *
aoqi@1 3357 * 104 mul [a6|I] [s0|I] [t0|I]
aoqi@1 3358 0x00000055655e3728: dmult a6, s0
aoqi@1 3359 0x00000055655e372c: sll zero, zero, 0
aoqi@1 3360 0x00000055655e3730: sll zero, zero, 0
aoqi@1 3361 0x00000055655e3734: mflo t0 <-- error
aoqi@1 3362 *
aoqi@1 3363 * t0: 0xFFFFFFFFcafebab0 (Right)
aoqi@1 3364 * t0: 0x00000000cafebab0 (Wrong)
aoqi@1 3365 */
aoqi@1 3366 if (dest->type() == T_INT)
aoqi@1 3367 __ sll(res, res, 0);
aoqi@1 3368 #endif
aoqi@1 3369 break;
aoqi@1 3370
aoqi@1 3371 case lir_sub:
aoqi@1 3372 #ifdef _LP64
aoqi@1 3373 if (dest->type() == T_INT)
aoqi@1 3374 __ subu32(res, lreg, rreg);
aoqi@1 3375 else
aoqi@1 3376 #endif
aoqi@1 3377 __ subu(res, lreg, rreg);
aoqi@1 3378 break;
aoqi@1 3379
aoqi@1 3380 default:
aoqi@1 3381 ShouldNotReachHere();
aoqi@1 3382 }
aoqi@1 3383 } else if (right->is_stack()) {
aoqi@1 3384 // cpu register - stack
aoqi@1 3385 Unimplemented();
aoqi@1 3386 } else if (right->is_constant()) {
aoqi@1 3387 // cpu register - constant
aoqi@1 3388 Register res = dest->as_register();
aoqi@1 3389 jint c = right->as_constant_ptr()->as_jint();
aoqi@1 3390
aoqi@1 3391 switch (code) {
aoqi@1 3392 case lir_mul_strictfp:
aoqi@1 3393 case lir_mul:
aoqi@1 3394 __ move(AT, c);
aoqi@1 3395 #ifndef _LP64
aoqi@1 3396 //by aoqi
aoqi@1 3397 __ mult(lreg, AT);
aoqi@1 3398 #else
aoqi@1 3399 __ dmult(lreg, AT);
aoqi@1 3400 #endif
aoqi@1 3401 __ nop();
aoqi@1 3402 __ nop();
aoqi@1 3403 __ mflo(res);
aoqi@1 3404 #ifdef _LP64
aoqi@1 3405 /* Jin: if res < 0, it must be sign-extended. Otherwise it will be a 64-bit positive number.
aoqi@1 3406 *
aoqi@1 3407 * Example: java.net.URLClassLoader::string2int()
aoqi@1 3408 * a6: 0xcafebab
aoqi@1 3409 * s0: 16
aoqi@1 3410 *
aoqi@1 3411 * 104 mul [a6|I] [s0|I] [t0|I]
aoqi@1 3412 0x00000055655e3728: dmult a6, s0
aoqi@1 3413 0x00000055655e372c: sll zero, zero, 0
aoqi@1 3414 0x00000055655e3730: sll zero, zero, 0
aoqi@1 3415 0x00000055655e3734: mflo t0 <-- error
aoqi@1 3416 *
aoqi@1 3417 * t0: 0xFFFFFFFFcafebab0 (Right)
aoqi@1 3418 * t0: 0x00000000cafebab0 (Wrong)
aoqi@1 3419 */
aoqi@1 3420 if (dest->type() == T_INT)
aoqi@1 3421 __ sll(res, res, 0);
aoqi@1 3422 #endif
aoqi@1 3423 break;
aoqi@1 3424
aoqi@1 3425 case lir_add:
aoqi@1 3426 if (Assembler::is_simm16(c)) {
aoqi@1 3427 __ addiu(res, lreg, c);
aoqi@1 3428 } else {
aoqi@1 3429 __ move(AT, c);
aoqi@1 3430 __ addu(res, lreg, AT);
aoqi@1 3431 }
aoqi@1 3432 break;
aoqi@1 3433
aoqi@1 3434 case lir_sub:
aoqi@1 3435 if (Assembler::is_simm16(-c)) {
aoqi@1 3436 __ addi(res, lreg, -c);
aoqi@1 3437 } else {
aoqi@1 3438 __ move(AT, c);
aoqi@1 3439 __ subu(res, lreg, AT);
aoqi@1 3440 }
aoqi@1 3441 break;
aoqi@1 3442
aoqi@1 3443 default:
aoqi@1 3444 ShouldNotReachHere();
aoqi@1 3445 }
aoqi@1 3446 } else {
aoqi@1 3447 ShouldNotReachHere();
aoqi@1 3448 }
aoqi@1 3449
aoqi@1 3450 } else if (left->is_double_cpu()) {
aoqi@1 3451 Register op1_lo = left->as_register_lo();
aoqi@1 3452 Register op1_hi = left->as_register_hi();
aoqi@1 3453 Register op2_lo;
aoqi@1 3454 Register op2_hi;
aoqi@1 3455 Register dst_lo;
aoqi@1 3456 Register dst_hi;
aoqi@1 3457
aoqi@1 3458 if(dest->is_single_cpu())
aoqi@1 3459 {
aoqi@1 3460 dst_lo = dest->as_register();
aoqi@1 3461 }
aoqi@1 3462 else
aoqi@1 3463 {
aoqi@1 3464 #ifdef _LP64
aoqi@1 3465 dst_lo = dest->as_register_lo();
aoqi@1 3466 #else
aoqi@1 3467 dst_lo = dest->as_register_lo();
aoqi@1 3468 dst_hi = dest->as_register_hi();
aoqi@1 3469 #endif
aoqi@1 3470 }
aoqi@1 3471 if (right->is_constant()) {
aoqi@1 3472 op2_lo = AT;
aoqi@1 3473 op2_hi = R0;
aoqi@1 3474 #ifndef _LP64
aoqi@1 3475 __ li(AT, right->as_constant_ptr()->as_jint());
aoqi@1 3476 #else
aoqi@1 3477 __ li(AT, right->as_constant_ptr()->as_jlong_bits());
aoqi@1 3478 #endif
aoqi@1 3479 } else if (right->is_double_cpu()) { // Double cpu
aoqi@1 3480 assert(right->is_double_cpu(),"right must be long");
aoqi@1 3481 assert(dest->is_double_cpu(), "dest must be long");
aoqi@1 3482 op2_lo = right->as_register_lo();
aoqi@1 3483 op2_hi = right->as_register_hi();
aoqi@1 3484 } else {
aoqi@1 3485 #ifdef _LP64
aoqi@1 3486 op2_lo = right->as_register();
aoqi@1 3487 #else
aoqi@1 3488 ShouldNotReachHere();
aoqi@1 3489 #endif
aoqi@1 3490 }
aoqi@1 3491
aoqi@1 3492 NOT_LP64(assert_different_registers(op1_lo, op1_hi, op2_lo, op2_hi));
aoqi@1 3493 // Jin: Why?
aoqi@1 3494 // LP64_ONLY(assert_different_registers(op1_lo, op2_lo));
aoqi@1 3495
aoqi@1 3496 switch (code) {
aoqi@1 3497 case lir_add:
aoqi@1 3498 #ifndef _LP64
aoqi@1 3499 //by aoqi
aoqi@1 3500 __ addu(dst_lo, op1_lo, op2_lo);
aoqi@1 3501 __ sltu(AT, dst_lo, op2_lo);
aoqi@1 3502 __ addu(dst_hi, op1_hi, op2_hi);
aoqi@1 3503 __ addu(dst_hi, dst_hi, AT);
aoqi@1 3504 #else
aoqi@1 3505 __ addu(dst_lo, op1_lo, op2_lo);
aoqi@1 3506 #endif
aoqi@1 3507 break;
aoqi@1 3508
aoqi@1 3509 case lir_sub:
aoqi@1 3510 #ifndef _LP64
aoqi@1 3511 //by aoqi
aoqi@1 3512 __ subu(dst_lo, op1_lo, op2_lo);
aoqi@1 3513 __ sltu(AT, op1_lo, dst_lo);
aoqi@1 3514 __ subu(dst_hi, op1_hi, op2_hi);
aoqi@1 3515 __ subu(dst_hi, dst_hi, AT);
aoqi@1 3516 #else
aoqi@1 3517 __ subu(dst_lo, op1_lo, op2_lo);
aoqi@1 3518 #endif
aoqi@1 3519 break;
aoqi@1 3520
aoqi@1 3521 case lir_mul:
aoqi@1 3522 {
aoqi@1 3523
aoqi@1 3524 #ifndef _LP64
aoqi@1 3525 //by aoqi
aoqi@1 3526 Label zero, quick, done;
aoqi@1 3527 //zero?
aoqi@1 3528 __ orr(AT, op2_lo, op1_lo);
aoqi@1 3529 __ beq(AT, R0, zero);
aoqi@1 3530 __ delayed();
aoqi@1 3531 __ move(dst_hi, R0);
aoqi@1 3532
aoqi@1 3533 //quick?
aoqi@1 3534 __ orr(AT, op2_hi, op1_hi);
aoqi@1 3535 __ beq(AT, R0, quick);
aoqi@1 3536 __ delayed()->nop();
aoqi@1 3537
aoqi@1 3538 __ multu(op2_lo, op1_hi);
aoqi@1 3539 __ nop();
aoqi@1 3540 __ nop();
aoqi@1 3541 __ mflo(dst_hi);
aoqi@1 3542 __ multu(op2_hi, op1_lo);
aoqi@1 3543 __ nop();
aoqi@1 3544 __ nop();
aoqi@1 3545 __ mflo(AT);
aoqi@1 3546
aoqi@1 3547 __ bind(quick);
aoqi@1 3548 __ multu(op2_lo, op1_lo);
aoqi@1 3549 __ addu(dst_hi, dst_hi, AT);
aoqi@1 3550 __ nop();
aoqi@1 3551 __ mflo(dst_lo);
aoqi@1 3552 __ mfhi(AT);
aoqi@1 3553 __ b(done);
aoqi@1 3554 __ delayed()->addu(dst_hi, dst_hi, AT);
aoqi@1 3555
aoqi@1 3556 __ bind(zero);
aoqi@1 3557 __ move(dst_lo, R0);
aoqi@1 3558 __ bind(done);
aoqi@1 3559 #else
aoqi@1 3560 Label zero, done;
aoqi@1 3561 //zero?
aoqi@1 3562 __ orr(AT, op2_lo, op1_lo);
aoqi@1 3563 __ beq(AT, R0, zero);
aoqi@1 3564 __ delayed();
aoqi@1 3565 __ move(dst_hi, R0);
aoqi@1 3566
aoqi@1 3567 #ifdef ASSERT
aoqi@1 3568 //op1_hi, op2_hi should be 0
aoqi@1 3569 {
aoqi@1 3570 Label L;
aoqi@1 3571 __ beq(op1_hi, R0, L);
aoqi@1 3572 __ delayed()->nop();
aoqi@1 3573 __ stop("wrong register, lir_mul");
aoqi@1 3574 __ bind(L);
aoqi@1 3575 }
aoqi@1 3576 {
aoqi@1 3577 Label L;
aoqi@1 3578 __ beq(op2_hi, R0, L);
aoqi@1 3579 __ delayed()->nop();
aoqi@1 3580 __ stop("wrong register, lir_mul");
aoqi@1 3581 __ bind(L);
aoqi@1 3582 }
aoqi@1 3583 #endif
aoqi@1 3584
aoqi@1 3585 __ multu(op2_lo, op1_lo);
aoqi@1 3586 __ nop();
aoqi@1 3587 __ nop();
aoqi@1 3588 __ mflo(dst_lo);
aoqi@1 3589 __ b(done);
aoqi@1 3590 __ delayed()->nop();
aoqi@1 3591
aoqi@1 3592 __ bind(zero);
aoqi@1 3593 __ move(dst_lo, R0);
aoqi@1 3594 __ bind(done);
aoqi@1 3595 #endif //_LP64
aoqi@1 3596 }
aoqi@1 3597 break;
aoqi@1 3598
aoqi@1 3599 default:
aoqi@1 3600 ShouldNotReachHere();
aoqi@1 3601 }
aoqi@1 3602
aoqi@1 3603
aoqi@1 3604 } else if (left->is_single_fpu()) {
aoqi@1 3605 assert(right->is_single_fpu(),"right must be float");
aoqi@1 3606 assert(dest->is_single_fpu(), "dest must be float");
aoqi@1 3607
aoqi@1 3608 FloatRegister lreg = left->as_float_reg();
aoqi@1 3609 FloatRegister rreg = right->as_float_reg();
aoqi@1 3610 FloatRegister res = dest->as_float_reg();
aoqi@1 3611
aoqi@1 3612 switch (code) {
aoqi@1 3613 case lir_add:
aoqi@1 3614 __ add_s(res, lreg, rreg);
aoqi@1 3615 break;
aoqi@1 3616 case lir_sub:
aoqi@1 3617 __ sub_s(res, lreg, rreg);
aoqi@1 3618 break;
aoqi@1 3619 case lir_mul:
aoqi@1 3620 case lir_mul_strictfp:
aoqi@1 3621 // i dont think we need special handling of this. FIXME
aoqi@1 3622 __ mul_s(res, lreg, rreg);
aoqi@1 3623 break;
aoqi@1 3624 case lir_div:
aoqi@1 3625 case lir_div_strictfp:
aoqi@1 3626 __ div_s(res, lreg, rreg);
aoqi@1 3627 break;
aoqi@1 3628 default : ShouldNotReachHere();
aoqi@1 3629 }
aoqi@1 3630 } else if (left->is_double_fpu()) {
aoqi@1 3631 assert(right->is_double_fpu(),"right must be double");
aoqi@1 3632 assert(dest->is_double_fpu(), "dest must be double");
aoqi@1 3633
aoqi@1 3634 FloatRegister lreg = left->as_double_reg();
aoqi@1 3635 FloatRegister rreg = right->as_double_reg();
aoqi@1 3636 FloatRegister res = dest->as_double_reg();
aoqi@1 3637
aoqi@1 3638 switch (code) {
aoqi@1 3639 case lir_add:
aoqi@1 3640 __ add_d(res, lreg, rreg);
aoqi@1 3641 break;
aoqi@1 3642 case lir_sub:
aoqi@1 3643 __ sub_d(res, lreg, rreg);
aoqi@1 3644 break;
aoqi@1 3645 case lir_mul:
aoqi@1 3646 case lir_mul_strictfp:
aoqi@1 3647 // i dont think we need special handling of this. FIXME
aoqi@1 3648 // by yjl 9/13/2005
aoqi@1 3649 __ mul_d(res, lreg, rreg);
aoqi@1 3650 break;
aoqi@1 3651 case lir_div:
aoqi@1 3652 case lir_div_strictfp:
aoqi@1 3653 __ div_d(res, lreg, rreg);
aoqi@1 3654 break;
aoqi@1 3655 // case lir_rem:
aoqi@1 3656 // __ rem_d(res, lreg, rreg);
aoqi@1 3657 // break;
aoqi@1 3658 default : ShouldNotReachHere();
aoqi@1 3659 }
aoqi@1 3660 }
aoqi@1 3661 else if (left->is_single_stack() || left->is_address()) {
aoqi@1 3662 assert(left == dest, "left and dest must be equal");
aoqi@1 3663
aoqi@1 3664 Address laddr;
aoqi@1 3665 if (left->is_single_stack()) {
aoqi@1 3666 laddr = frame_map()->address_for_slot(left->single_stack_ix());
aoqi@1 3667 } else if (left->is_address()) {
aoqi@1 3668 laddr = as_Address(left->as_address_ptr());
aoqi@1 3669 } else {
aoqi@1 3670 ShouldNotReachHere();
aoqi@1 3671 }
aoqi@1 3672
aoqi@1 3673 if (right->is_single_cpu()) {
aoqi@1 3674 Register rreg = right->as_register();
aoqi@1 3675 switch (code) {
aoqi@1 3676 case lir_add:
aoqi@1 3677 #ifndef _LP64
aoqi@1 3678 //by aoqi
aoqi@1 3679 __ lw(AT, laddr);
aoqi@1 3680 __ add(AT, AT, rreg);
aoqi@1 3681 __ sw(AT, laddr);
aoqi@1 3682 #else
aoqi@1 3683 __ ld(AT, laddr);
aoqi@1 3684 __ dadd(AT, AT, rreg);
aoqi@1 3685 __ sd(AT, laddr);
aoqi@1 3686 #endif
aoqi@1 3687 break;
aoqi@1 3688 case lir_sub:
aoqi@1 3689 #ifndef _LP64
aoqi@1 3690 //by aoqi
aoqi@1 3691 __ lw(AT, laddr);
aoqi@1 3692 __ sub(AT,AT,rreg);
aoqi@1 3693 __ sw(AT, laddr);
aoqi@1 3694 #else
aoqi@1 3695 __ ld(AT, laddr);
aoqi@1 3696 __ dsub(AT,AT,rreg);
aoqi@1 3697 __ sd(AT, laddr);
aoqi@1 3698 #endif
aoqi@1 3699 break;
aoqi@1 3700 default: ShouldNotReachHere();
aoqi@1 3701 }
aoqi@1 3702 } else if (right->is_constant()) {
aoqi@1 3703 #ifndef _LP64
aoqi@1 3704 jint c = right->as_constant_ptr()->as_jint();
aoqi@1 3705 #else
aoqi@1 3706 jlong c = right->as_constant_ptr()->as_jlong_bits();
aoqi@1 3707 #endif
aoqi@1 3708 switch (code) {
aoqi@1 3709 case lir_add: {
aoqi@1 3710 __ ld_ptr(AT, laddr);
aoqi@1 3711 #ifndef _LP64
aoqi@1 3712 __ addi(AT, AT, c);
aoqi@1 3713 #else
aoqi@1 3714 __ li(T8, c);
aoqi@1 3715 __ add(AT, AT, T8);
aoqi@1 3716 #endif
aoqi@1 3717 __ st_ptr(AT, laddr);
aoqi@1 3718 break;
aoqi@1 3719 }
aoqi@1 3720 case lir_sub: {
aoqi@1 3721 __ ld_ptr(AT, laddr);
aoqi@1 3722 #ifndef _LP64
aoqi@1 3723 __ addi(AT, AT, -c);
aoqi@1 3724 #else
aoqi@1 3725 __ li(T8, -c);
aoqi@1 3726 __ add(AT, AT, T8);
aoqi@1 3727 #endif
aoqi@1 3728 __ st_ptr(AT, laddr);
aoqi@1 3729 break;
aoqi@1 3730 }
aoqi@1 3731 default: ShouldNotReachHere();
aoqi@1 3732 }
aoqi@1 3733 } else {
aoqi@1 3734 ShouldNotReachHere();
aoqi@1 3735 }
aoqi@1 3736 } else {
aoqi@1 3737 ShouldNotReachHere();
aoqi@1 3738 }
aoqi@1 3739 }
aoqi@1 3740
aoqi@1 3741 void LIR_Assembler::intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr unused, LIR_Opr dest, LIR_Op *op) {
aoqi@1 3742 //FIXME,lir_log, lir_log10,lir_abs,lir_sqrt,so many new lir instruction @jerome
aoqi@1 3743 if (value->is_double_fpu()) {
aoqi@1 3744 // assert(value->fpu_regnrLo() == 0 && dest->fpu_regnrLo() == 0, "both must be on TOS");
aoqi@1 3745 switch(code) {
aoqi@1 3746 case lir_log : //__ flog() ; break;
aoqi@1 3747 case lir_log10 : //__ flog10() ;
aoqi@1 3748 Unimplemented();
aoqi@1 3749 break;
aoqi@1 3750 case lir_abs : __ abs_d(dest->as_double_reg(), value->as_double_reg()) ; break;
aoqi@1 3751 case lir_sqrt : __ sqrt_d(dest->as_double_reg(), value->as_double_reg()); break;
aoqi@1 3752 case lir_sin :
aoqi@1 3753 // Should consider not saving ebx if not necessary
aoqi@1 3754 __ trigfunc('s', 0);
aoqi@1 3755 break;
aoqi@1 3756 case lir_cos :
aoqi@1 3757 // Should consider not saving ebx if not necessary
aoqi@1 3758 // assert(op->as_Op2()->fpu_stack_size() <= 6, "sin and cos need two free stack slots");
aoqi@1 3759 __ trigfunc('c', 0);
aoqi@1 3760 break;
aoqi@1 3761 case lir_tan :
aoqi@1 3762 // Should consider not saving ebx if not necessary
aoqi@1 3763 __ trigfunc('t', 0);
aoqi@1 3764 break;
aoqi@1 3765 default : ShouldNotReachHere();
aoqi@1 3766 }
aoqi@1 3767 } else {
aoqi@1 3768 Unimplemented();
aoqi@1 3769 }
aoqi@1 3770 }
aoqi@1 3771
aoqi@1 3772 //FIXME, if right is on the stack!
aoqi@1 3773 void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst) {
aoqi@1 3774 if (left->is_single_cpu()) {
aoqi@1 3775 Register dstreg = dst->as_register();
aoqi@1 3776 Register reg = left->as_register();
aoqi@1 3777 if (right->is_constant()) {
aoqi@1 3778 int val = right->as_constant_ptr()->as_jint();
aoqi@1 3779 __ move(AT, val);
aoqi@1 3780 switch (code) {
aoqi@1 3781 case lir_logic_and:
aoqi@1 3782 __ andr (dstreg, reg, AT);
aoqi@1 3783 break;
aoqi@1 3784 case lir_logic_or:
aoqi@1 3785 __ orr(dstreg, reg, AT);
aoqi@1 3786 break;
aoqi@1 3787 case lir_logic_xor:
aoqi@1 3788 __ xorr(dstreg, reg, AT);
aoqi@1 3789 break;
aoqi@1 3790 default: ShouldNotReachHere();
aoqi@1 3791 }
aoqi@1 3792 } else if (right->is_stack()) {
aoqi@1 3793 // added support for stack operands
aoqi@1 3794 Address raddr = frame_map()->address_for_slot(right->single_stack_ix());
aoqi@1 3795 switch (code) {
aoqi@1 3796 case lir_logic_and:
aoqi@1 3797 //FIXME. lw or ld_ptr?
aoqi@1 3798 __ lw(AT, raddr);
aoqi@1 3799 __ andr(reg, reg,AT);
aoqi@1 3800 break;
aoqi@1 3801 case lir_logic_or:
aoqi@1 3802 __ lw(AT, raddr);
aoqi@1 3803 __ orr(reg, reg, AT);
aoqi@1 3804 break;
aoqi@1 3805 case lir_logic_xor:
aoqi@1 3806 __ lw(AT, raddr);
aoqi@1 3807 __ xorr(reg, reg, AT);
aoqi@1 3808 break;
aoqi@1 3809 default: ShouldNotReachHere();
aoqi@1 3810 }
aoqi@1 3811 } else {
aoqi@1 3812 Register rright = right->as_register();
aoqi@1 3813 switch (code) {
aoqi@1 3814 case lir_logic_and: __ andr (dstreg, reg, rright); break;
aoqi@1 3815 case lir_logic_or : __ orr (dstreg, reg, rright); break;
aoqi@1 3816 case lir_logic_xor: __ xorr (dstreg, reg, rright); break;
aoqi@1 3817 default: ShouldNotReachHere();
aoqi@1 3818 }
aoqi@1 3819 }
aoqi@1 3820 } else {
aoqi@1 3821 Register l_lo = left->as_register_lo();
aoqi@1 3822 Register dst_lo = dst->as_register_lo();
aoqi@1 3823 #ifndef _LP64
aoqi@1 3824 Register l_hi = left->as_register_hi();
aoqi@1 3825 Register dst_hi = dst->as_register_hi();
aoqi@1 3826 #endif
aoqi@1 3827
aoqi@1 3828 if (right->is_constant()) {
aoqi@1 3829 #ifndef _LP64
aoqi@1 3830
aoqi@1 3831 int r_lo = right->as_constant_ptr()->as_jint_lo();
aoqi@1 3832 int r_hi = right->as_constant_ptr()->as_jint_hi();
aoqi@1 3833
aoqi@1 3834 switch (code) {
aoqi@1 3835 case lir_logic_and:
aoqi@1 3836 __ move(AT, r_lo);
aoqi@1 3837 __ andr(dst_lo, l_lo, AT);
aoqi@1 3838 __ move(AT, r_hi);
aoqi@1 3839 __ andr(dst_hi, l_hi, AT);
aoqi@1 3840 break;
aoqi@1 3841
aoqi@1 3842 case lir_logic_or:
aoqi@1 3843 __ move(AT, r_lo);
aoqi@1 3844 __ orr(dst_lo, l_lo, AT);
aoqi@1 3845 __ move(AT, r_hi);
aoqi@1 3846 __ orr(dst_hi, l_hi, AT);
aoqi@1 3847 break;
aoqi@1 3848
aoqi@1 3849 case lir_logic_xor:
aoqi@1 3850 __ move(AT, r_lo);
aoqi@1 3851 __ xorr(dst_lo, l_lo, AT);
aoqi@1 3852 __ move(AT, r_hi);
aoqi@1 3853 __ xorr(dst_hi, l_hi, AT);
aoqi@1 3854 break;
aoqi@1 3855
aoqi@1 3856 default: ShouldNotReachHere();
aoqi@1 3857 }
aoqi@1 3858 #else
aoqi@1 3859 __ li(AT, right->as_constant_ptr()->as_jlong());
aoqi@1 3860
aoqi@1 3861 switch (code) {
aoqi@1 3862 case lir_logic_and:
aoqi@1 3863 __ andr(dst_lo, l_lo, AT);
aoqi@1 3864 break;
aoqi@1 3865
aoqi@1 3866 case lir_logic_or:
aoqi@1 3867 __ orr(dst_lo, l_lo, AT);
aoqi@1 3868 break;
aoqi@1 3869
aoqi@1 3870 case lir_logic_xor:
aoqi@1 3871 __ xorr(dst_lo, l_lo, AT);
aoqi@1 3872 break;
aoqi@1 3873
aoqi@1 3874 default: ShouldNotReachHere();
aoqi@1 3875 }
aoqi@1 3876 #endif
aoqi@1 3877
aoqi@1 3878 } else {
aoqi@1 3879 Register r_lo = right->as_register_lo();
aoqi@1 3880 Register r_hi = right->as_register_hi();
aoqi@1 3881
aoqi@1 3882 switch (code) {
aoqi@1 3883 case lir_logic_and:
aoqi@1 3884 __ andr(dst_lo, l_lo, r_lo);
aoqi@1 3885 NOT_LP64(__ andr(dst_hi, l_hi, r_hi);)
aoqi@1 3886 break;
aoqi@1 3887 case lir_logic_or:
aoqi@1 3888 __ orr(dst_lo, l_lo, r_lo);
aoqi@1 3889 NOT_LP64(__ orr(dst_hi, l_hi, r_hi);)
aoqi@1 3890 break;
aoqi@1 3891 case lir_logic_xor:
aoqi@1 3892 __ xorr(dst_lo, l_lo, r_lo);
aoqi@1 3893 NOT_LP64(__ xorr(dst_hi, l_hi, r_hi);)
aoqi@1 3894 break;
aoqi@1 3895 default: ShouldNotReachHere();
aoqi@1 3896 }
aoqi@1 3897 }
aoqi@1 3898 }
aoqi@1 3899 }
aoqi@1 3900
aoqi@1 3901 //done here. aoqi. 12-12 22:25
aoqi@1 3902 // we assume that eax and edx can be overwritten
aoqi@1 3903 void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info) {
aoqi@1 3904
aoqi@1 3905 assert(left->is_single_cpu(), "left must be register");
aoqi@1 3906 assert(right->is_single_cpu() || right->is_constant(), "right must be register or constant");
aoqi@1 3907 assert(result->is_single_cpu(), "result must be register");
aoqi@1 3908
aoqi@1 3909 Register lreg = left->as_register();
aoqi@1 3910 Register dreg = result->as_register();
aoqi@1 3911
aoqi@1 3912 if (right->is_constant()) {
aoqi@1 3913 int divisor = right->as_constant_ptr()->as_jint();
aoqi@1 3914 assert(divisor!=0, "must be nonzero");
aoqi@1 3915 #ifndef _LP64
aoqi@1 3916 __ move(AT, divisor);
aoqi@1 3917 __ div(lreg, AT);
aoqi@1 3918 #else
aoqi@1 3919 __ li(AT, divisor);
aoqi@1 3920 __ ddiv(lreg, AT);
aoqi@1 3921 #endif
aoqi@1 3922 int idivl_offset = code_offset();
aoqi@1 3923
aoqi@1 3924 /* 2012/4/21 Jin: In MIPS, div does not cause exception.
aoqi@1 3925 We must trap an exception manually. */
aoqi@1 3926 __ teq(R0, AT, 0x7);
aoqi@1 3927 __ nop();
aoqi@1 3928 __ nop();
aoqi@1 3929 add_debug_info_for_div0(idivl_offset, info);
aoqi@1 3930 } else {
aoqi@1 3931 Register rreg = right->as_register();
aoqi@1 3932 #ifndef _LP64
aoqi@1 3933 __ div(lreg, rreg);
aoqi@1 3934 #else
aoqi@1 3935 __ ddiv(lreg, rreg);
aoqi@1 3936 #endif
aoqi@1 3937
aoqi@1 3938 int idivl_offset = code_offset();
aoqi@1 3939 __ teq(R0, rreg, 0x7);
aoqi@1 3940 __ nop();
aoqi@1 3941 __ nop();
aoqi@1 3942 add_debug_info_for_div0(idivl_offset, info);
aoqi@1 3943 }
aoqi@1 3944
aoqi@1 3945 // get the result
aoqi@1 3946 if (code == lir_irem) {
aoqi@1 3947 __ mfhi(dreg);
aoqi@1 3948 #ifdef _LP64
aoqi@1 3949 if (result->type() == T_INT)
aoqi@1 3950 __ sll(dreg, dreg, 0);
aoqi@1 3951 #endif
aoqi@1 3952 } else if (code == lir_idiv) {
aoqi@1 3953 __ mflo(dreg);
aoqi@1 3954 } else {
aoqi@1 3955 ShouldNotReachHere();
aoqi@1 3956 }
aoqi@1 3957 }
aoqi@1 3958
aoqi@1 3959 void LIR_Assembler::arithmetic_frem(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info) {
aoqi@1 3960 if (left->is_single_fpu()) {
aoqi@1 3961 assert(right->is_single_fpu(),"right must be float");
aoqi@1 3962 assert(result->is_single_fpu(), "dest must be float");
aoqi@1 3963 assert(temp->is_single_fpu(), "dest must be float");
aoqi@1 3964
aoqi@1 3965 FloatRegister lreg = left->as_float_reg();
aoqi@1 3966 FloatRegister rreg = right->as_float_reg();
aoqi@1 3967 FloatRegister res = result->as_float_reg();
aoqi@1 3968 FloatRegister tmp = temp->as_float_reg();
aoqi@1 3969
aoqi@1 3970 switch (code) {
aoqi@1 3971 case lir_frem:
aoqi@1 3972 __ rem_s(res, lreg, rreg, tmp);
aoqi@1 3973 break;
aoqi@1 3974 default : ShouldNotReachHere();
aoqi@1 3975 }
aoqi@1 3976 } else if (left->is_double_fpu()) {
aoqi@1 3977 assert(right->is_double_fpu(),"right must be double");
aoqi@1 3978 assert(result->is_double_fpu(), "dest must be double");
aoqi@1 3979 assert(temp->is_double_fpu(), "dest must be double");
aoqi@1 3980
aoqi@1 3981 FloatRegister lreg = left->as_double_reg();
aoqi@1 3982 FloatRegister rreg = right->as_double_reg();
aoqi@1 3983 FloatRegister res = result->as_double_reg();
aoqi@1 3984 FloatRegister tmp = temp->as_double_reg();
aoqi@1 3985
aoqi@1 3986 switch (code) {
aoqi@1 3987 case lir_frem:
aoqi@1 3988 __ rem_d(res, lreg, rreg, tmp);
aoqi@1 3989 break;
aoqi@1 3990 default : ShouldNotReachHere();
aoqi@1 3991 }
aoqi@1 3992 }
aoqi@1 3993 }
aoqi@1 3994
aoqi@1 3995 void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst,LIR_Op2 * op) {
aoqi@1 3996 Register dstreg = dst->as_register();
aoqi@1 3997 if (code == lir_cmp_fd2i) {
aoqi@1 3998 if (left->is_single_fpu()) {
aoqi@1 3999 FloatRegister leftreg = left->as_float_reg();
aoqi@1 4000 FloatRegister rightreg = right->as_float_reg();
aoqi@1 4001
aoqi@1 4002 Label done;
aoqi@1 4003 // equal?
aoqi@1 4004 __ c_eq_s(leftreg, rightreg);
aoqi@1 4005 __ bc1t(done);
aoqi@1 4006 __ delayed();
aoqi@1 4007 __ move(dstreg, R0);
aoqi@1 4008 // less?
aoqi@1 4009 __ c_olt_s(leftreg, rightreg);
aoqi@1 4010 __ bc1t(done);
aoqi@1 4011 __ delayed();
aoqi@1 4012 __ move(dstreg, -1);
aoqi@1 4013 // great
aoqi@1 4014 __ move(dstreg, 1);
aoqi@1 4015
aoqi@1 4016 __ bind(done);
aoqi@1 4017 } else {
aoqi@1 4018 assert(left->is_double_fpu(), "Must double");
aoqi@1 4019 FloatRegister leftreg = left->as_double_reg();
aoqi@1 4020 FloatRegister rightreg = right->as_double_reg();
aoqi@1 4021
aoqi@1 4022 Label done;
aoqi@1 4023 // equal?
aoqi@1 4024 __ c_eq_d(leftreg, rightreg);
aoqi@1 4025 __ bc1t(done);
aoqi@1 4026 __ delayed();
aoqi@1 4027 __ move(dstreg, R0);
aoqi@1 4028 // less?
aoqi@1 4029 __ c_olt_d(leftreg, rightreg);
aoqi@1 4030 __ bc1t(done);
aoqi@1 4031 __ delayed();
aoqi@1 4032 __ move(dstreg, -1);
aoqi@1 4033 // great
aoqi@1 4034 __ move(dstreg, 1);
aoqi@1 4035
aoqi@1 4036 __ bind(done);
aoqi@1 4037 }
aoqi@1 4038 } else if (code == lir_ucmp_fd2i) {
aoqi@1 4039 if (left->is_single_fpu()) {
aoqi@1 4040 FloatRegister leftreg = left->as_float_reg();
aoqi@1 4041 FloatRegister rightreg = right->as_float_reg();
aoqi@1 4042
aoqi@1 4043 Label done;
aoqi@1 4044 // equal?
aoqi@1 4045 __ c_eq_s(leftreg, rightreg);
aoqi@1 4046 __ bc1t(done);
aoqi@1 4047 __ delayed();
aoqi@1 4048 __ move(dstreg, R0);
aoqi@1 4049 // less?
aoqi@1 4050 __ c_ult_s(leftreg, rightreg);
aoqi@1 4051 __ bc1t(done);
aoqi@1 4052 __ delayed();
aoqi@1 4053 __ move(dstreg, -1);
aoqi@1 4054 // great
aoqi@1 4055 __ move(dstreg, 1);
aoqi@1 4056
aoqi@1 4057 __ bind(done);
aoqi@1 4058 } else {
aoqi@1 4059 assert(left->is_double_fpu(), "Must double");
aoqi@1 4060 FloatRegister leftreg = left->as_double_reg();
aoqi@1 4061 FloatRegister rightreg = right->as_double_reg();
aoqi@1 4062
aoqi@1 4063 Label done;
aoqi@1 4064 // equal?
aoqi@1 4065 __ c_eq_d(leftreg, rightreg);
aoqi@1 4066 __ bc1t(done);
aoqi@1 4067 __ delayed();
aoqi@1 4068 __ move(dstreg, R0);
aoqi@1 4069 // less?
aoqi@1 4070 __ c_ult_d(leftreg, rightreg);
aoqi@1 4071 __ bc1t(done);
aoqi@1 4072 __ delayed();
aoqi@1 4073 __ move(dstreg, -1);
aoqi@1 4074 // great
aoqi@1 4075 __ move(dstreg, 1);
aoqi@1 4076
aoqi@1 4077 __ bind(done);
aoqi@1 4078 }
aoqi@1 4079 } else {
aoqi@1 4080 assert(code == lir_cmp_l2i, "check");
aoqi@1 4081 Register l_lo, l_hi, r_lo, r_hi, d_lo, d_hi;
aoqi@1 4082 l_lo = left->as_register_lo();
aoqi@1 4083 l_hi = left->as_register_hi();
aoqi@1 4084 r_lo = right->as_register_lo();
aoqi@1 4085 r_hi = right->as_register_hi();
aoqi@1 4086
aoqi@1 4087 Label done;
aoqi@1 4088 #ifndef _LP64
aoqi@1 4089 // less?
aoqi@1 4090 __ slt(AT, l_hi, r_hi);
aoqi@1 4091 __ bne(AT, R0, done);
aoqi@1 4092 __ delayed();
aoqi@1 4093 __ move(dstreg, -1);
aoqi@1 4094 // great?
aoqi@1 4095 __ slt(AT, r_hi, l_hi);
aoqi@1 4096 __ bne(AT, R0, done);
aoqi@1 4097 __ delayed();
aoqi@1 4098 __ move(dstreg, 1);
aoqi@1 4099 #endif
aoqi@1 4100
aoqi@1 4101 // now compare low 32 bits
aoqi@1 4102 // below?
aoqi@1 4103 #ifndef _LP64
aoqi@1 4104 __ sltu(AT, l_lo, r_lo);
aoqi@1 4105 #else
aoqi@1 4106 __ slt(AT, l_lo, r_lo);
aoqi@1 4107 #endif
aoqi@1 4108 __ bne(AT, R0, done);
aoqi@1 4109 __ delayed();
aoqi@1 4110 __ move(dstreg, -1);
aoqi@1 4111 // above?
aoqi@1 4112 #ifndef _LP64
aoqi@1 4113 __ sltu(AT, r_lo, l_lo);
aoqi@1 4114 #else
aoqi@1 4115 __ slt(AT, r_lo, l_lo);
aoqi@1 4116 #endif
aoqi@1 4117 __ bne(AT, R0, done);
aoqi@1 4118 __ delayed();
aoqi@1 4119 __ move(dstreg, 1);
aoqi@1 4120 // equal
aoqi@1 4121 __ move(dstreg, R0);
aoqi@1 4122
aoqi@1 4123 __ bind(done);
aoqi@1 4124 }
aoqi@1 4125 }
aoqi@1 4126
aoqi@1 4127
aoqi@1 4128 void LIR_Assembler::align_call(LIR_Code code) {
aoqi@1 4129 //FIXME. aoqi, this right?
aoqi@1 4130 // do nothing since all instructions are word aligned on sparc
aoqi@1 4131 /*
aoqi@1 4132 if (os::is_MP()) {
aoqi@1 4133 // make sure that the displacement word of the call ends up word aligned
aoqi@1 4134 int offset = __ offset();
aoqi@1 4135 switch (code) {
aoqi@1 4136 case lir_static_call:
aoqi@1 4137 case lir_optvirtual_call:
aoqi@1 4138 offset += NativeCall::displacement_offset;
aoqi@1 4139 break;
aoqi@1 4140 case lir_icvirtual_call:
aoqi@1 4141 offset += NativeCall::displacement_offset + NativeMovConstReg::instruction_size;
aoqi@1 4142 break;
aoqi@1 4143 case lir_virtual_call: // currently, sparc-specific for niagara
aoqi@1 4144 default: ShouldNotReachHere();
aoqi@1 4145 }
aoqi@1 4146 while (offset++ % BytesPerWord != 0) {
aoqi@1 4147 __ nop();
aoqi@1 4148 }
aoqi@1 4149 }
aoqi@1 4150 */
aoqi@1 4151 }
aoqi@1 4152
aoqi@1 4153
aoqi@1 4154 void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) {
aoqi@1 4155 //assert(!os::is_MP() || (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0, "must be aligned");
aoqi@1 4156 __ call(op->addr(), rtype);
aoqi@1 4157 __ delayed()->nop();
aoqi@1 4158 add_call_info(code_offset(), op->info());
aoqi@1 4159 }
aoqi@1 4160
aoqi@1 4161
aoqi@1 4162 void LIR_Assembler::ic_call(LIR_OpJavaCall* op) {
aoqi@1 4163 RelocationHolder rh = virtual_call_Relocation::spec(pc());
aoqi@1 4164 // int oop_index = __ oop_recorder()->allocate_oop_index((jobject)Universe::non_oop_word());
aoqi@1 4165 // RelocationHolder rspec = oop_Relocation::spec(oop_index);
aoqi@1 4166 /// __ relocate(rspec);
aoqi@1 4167 #ifndef _LP64
aoqi@1 4168 //by_css
aoqi@1 4169 __ lui(IC_Klass, Assembler::split_high((int)Universe::non_oop_word()));
aoqi@1 4170 __ addiu(IC_Klass, IC_Klass, Assembler::split_low((int)Universe::non_oop_word()));
aoqi@1 4171 #else
aoqi@1 4172 __ li48(IC_Klass, (long)Universe::non_oop_word());
aoqi@1 4173 #endif
aoqi@1 4174 __ call(op->addr(), rh);
aoqi@1 4175 __ delayed()->nop();
aoqi@1 4176 // add_call_info(code_offset(), info);
aoqi@1 4177
aoqi@1 4178 add_call_info(code_offset(), op->info());
aoqi@1 4179 assert(!os::is_MP() ||
aoqi@1 4180 (__ offset() - NativeCall::instruction_size + NativeCall::displacement_offset) % BytesPerWord == 0,
aoqi@1 4181 "must be aligned");
aoqi@1 4182
aoqi@1 4183 }
aoqi@1 4184
aoqi@1 4185
aoqi@1 4186 /* Currently, vtable-dispatch is only enabled for sparc platforms */
aoqi@1 4187 void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) {
aoqi@1 4188 ShouldNotReachHere();
aoqi@1 4189 }
aoqi@1 4190
aoqi@1 4191
aoqi@1 4192
aoqi@1 4193 void LIR_Assembler::emit_static_call_stub() {
aoqi@1 4194 address call_pc = __ pc();
aoqi@1 4195 address stub = __ start_a_stub(call_stub_size);
aoqi@1 4196 if (stub == NULL) {
aoqi@1 4197 bailout("static call stub overflow");
aoqi@1 4198 return;
aoqi@1 4199 }
aoqi@1 4200
aoqi@1 4201 int start = __ offset();
aoqi@1 4202 /*
aoqi@1 4203 if (os::is_MP()) {
aoqi@1 4204 // make sure that the displacement word of the call ends up word aligned
aoqi@1 4205 int offset = __ offset() + NativeMovConstReg::instruction_size + NativeCall::displacement_offset;
aoqi@1 4206 while (offset++ % BytesPerWord != 0) {
aoqi@1 4207 __ nop();
aoqi@1 4208 }
aoqi@1 4209 }
aoqi@1 4210 */
aoqi@1 4211 __ relocate(static_stub_Relocation::spec(call_pc));
aoqi@1 4212 jobject o=NULL;
aoqi@1 4213 int oop_index = __ oop_recorder()->allocate_oop_index((jobject)o);
aoqi@1 4214 RelocationHolder rspec = oop_Relocation::spec(oop_index);
aoqi@1 4215 __ relocate(rspec);
aoqi@1 4216 //see set_to_interpreted
aoqi@1 4217 #ifndef _LP64
aoqi@1 4218 __ lui(T7, Assembler::split_high((int)o));
aoqi@1 4219 __ addiu(T7, T7, Assembler::split_low((int)o));
aoqi@1 4220 #else
aoqi@1 4221 __ li48(Rmethod, (long)o);
aoqi@1 4222 #endif
aoqi@1 4223 #ifndef _LP64
aoqi@1 4224 __ lui(AT, Assembler::split_high((int)-1));
aoqi@1 4225 __ addiu(AT, AT, Assembler::split_low((int)-1));
aoqi@1 4226 #else
aoqi@1 4227 __ li48(AT, (long)-1);
aoqi@1 4228 #endif
aoqi@1 4229 //assert(!os::is_MP() || ((__ offset() + 1) % BytesPerWord) == 0, "must be aligned on MP");
aoqi@1 4230 __ jr(AT);
aoqi@1 4231 __ delayed()->nop();
aoqi@1 4232 assert(__ offset() - start <= call_stub_size, "stub too big");
aoqi@1 4233 __ end_a_stub();
aoqi@1 4234 }
aoqi@1 4235
aoqi@1 4236
aoqi@1 4237 void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) {
aoqi@1 4238 assert(exceptionOop->as_register()== V0, "must match");
aoqi@1 4239 assert(exceptionPC->as_register()== V1, "must match");
aoqi@1 4240
aoqi@1 4241 // exception object is not added to oop map by LinearScan
aoqi@1 4242 // (LinearScan assumes that no oops are in fixed registers)
aoqi@1 4243
aoqi@1 4244 info->add_register_oop(exceptionOop);
aoqi@1 4245 //if (!unwind) {
aoqi@1 4246 // get current pc information
aoqi@1 4247 // pc is only needed if the method has an exception handler, the unwind code does not need it.
aoqi@1 4248 #ifndef _LP64
aoqi@1 4249 //by_css
aoqi@1 4250 int pc_for_athrow = (int)__ pc();
aoqi@1 4251 int pc_for_athrow_offset = __ offset();
aoqi@1 4252 Register epc = exceptionPC->as_register();
aoqi@1 4253 //__ nop();
aoqi@1 4254 // pc_for_athrow can not point to itself (relocInfo restriction), no need now
aoqi@1 4255 __ relocate(relocInfo::internal_pc_type);
aoqi@1 4256 __ lui(epc, Assembler::split_high(pc_for_athrow));
aoqi@1 4257 __ addiu(epc, epc, Assembler::split_low(pc_for_athrow));
aoqi@1 4258 #else
aoqi@1 4259 long pc_for_athrow = (long)__ pc();
aoqi@1 4260 int pc_for_athrow_offset = __ offset();
aoqi@1 4261 Register epc = exceptionPC->as_register();
aoqi@1 4262 //__ nop();
aoqi@1 4263 // pc_for_athrow can not point to itself (relocInfo restriction), no need now
aoqi@1 4264 __ relocate(relocInfo::internal_pc_type);
aoqi@1 4265 __ li48(epc, pc_for_athrow);
aoqi@1 4266 #endif
aoqi@1 4267 add_call_info(pc_for_athrow_offset, info); // for exception handler
aoqi@1 4268 __ verify_not_null_oop(V0);
aoqi@1 4269 // search an exception handler (eax: exception oop, edx: throwing pc)
aoqi@1 4270 if (compilation()->has_fpu_code()) {
aoqi@1 4271 __ call(Runtime1::entry_for(Runtime1::handle_exception_id),
aoqi@1 4272 relocInfo::runtime_call_type);
aoqi@1 4273 } else {
aoqi@1 4274 __ call(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id),
aoqi@1 4275 relocInfo::runtime_call_type);
aoqi@1 4276 }
aoqi@1 4277 // } else {
aoqi@1 4278 // __ call(Runtime1::entry_for(Runtime1::unwind_exception_id),
aoqi@1 4279 // relocInfo::runtime_call_type);
aoqi@1 4280 // }
aoqi@1 4281
aoqi@1 4282 // enough room for two byte trap
aoqi@1 4283 __ delayed()->nop();
aoqi@1 4284 }
aoqi@1 4285
aoqi@1 4286 void LIR_Assembler::unwind_op(LIR_Opr exceptionOop){
aoqi@1 4287 assert(exceptionOop->as_register()== FSR, "must match");
aoqi@1 4288 __ b(_unwind_handler_entry);
aoqi@1 4289 __ delayed()->nop();
aoqi@1 4290 }
aoqi@1 4291
aoqi@1 4292 void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) {
aoqi@1 4293 // optimized version for linear scan:
aoqi@1 4294 // * tmp must be unused
aoqi@1 4295 assert(tmp->is_illegal(), "wasting a register if tmp is allocated");
aoqi@1 4296
aoqi@1 4297 #ifdef _LP64
aoqi@1 4298 Register count_reg = count->as_register();
aoqi@1 4299 Register value_reg;
aoqi@1 4300 Register dest_reg;
aoqi@1 4301 if (left->is_single_cpu()) {
aoqi@1 4302 value_reg = left->as_register();
aoqi@1 4303 dest_reg = dest->as_register();
aoqi@1 4304
aoqi@1 4305 } else if (left->is_double_cpu()) {
aoqi@1 4306 value_reg = left->as_register_lo();
aoqi@1 4307 dest_reg = dest->as_register_lo();
aoqi@1 4308 } else {
aoqi@1 4309 ShouldNotReachHere();
aoqi@1 4310 }
aoqi@1 4311 assert_different_registers(count_reg, value_reg);
aoqi@1 4312 switch (code) {
aoqi@1 4313 case lir_shl:
aoqi@1 4314 if (dest->type() == T_INT)
aoqi@1 4315 __ sllv(dest_reg, value_reg, count_reg);
aoqi@1 4316 else
aoqi@1 4317 __ dsllv(dest_reg, value_reg, count_reg);
aoqi@1 4318 break;
aoqi@1 4319 //__ dsllv(dest_reg, value_reg, count_reg); break;
aoqi@1 4320 case lir_shr: __ dsrav(dest_reg, value_reg, count_reg); break;
aoqi@1 4321 case lir_ushr:
aoqi@1 4322 #if 1
aoqi@1 4323 /*
aoqi@1 4324 Jin: in java, ushift_right requires 32-bit UNSIGNED operation!
aoqi@1 4325 However, dsrl will shift in company with the highest 32 bits.
aoqi@1 4326 Thus, if the source register contains a negative value,
aoqi@1 4327 the resulti is incorrect.
aoqi@1 4328 * DoubleCvt.java
aoqi@1 4329 *
aoqi@1 4330 * static int inp (int shift)
aoqi@1 4331 * {
aoqi@1 4332 * return -1 >>> (32 - shift);
aoqi@1 4333 * }
aoqi@1 4334 *
aoqi@1 4335 * 26 ushift_right [t0|I] [a4|I] [a6|I]
aoqi@1 4336 * 0x00000055616d2a98: dsrl a6, t0, a4 <-- error
aoqi@1 4337 */
aoqi@1 4338
aoqi@1 4339 // java.math.MutableBigInteger::primitiveRightShift
aoqi@1 4340 //
aoqi@1 4341 // 108 ushift_right [a6|I] [a4|I] [a4|I]
aoqi@1 4342 // 0x00000055646d2f70: dsll32 a4, a6, 0 \
aoqi@1 4343 // 0x00000055646d2f74: dsrl32 a4, a4, 0 |- error!
aoqi@1 4344 // 0x00000055646d2f78: dsrl a4, a4, a4 /
aoqi@1 4345 if (left->type() == T_INT && dest->type() == T_INT)
aoqi@1 4346 {
aoqi@1 4347 __ dsll32(AT, value_reg, 0); // Omit the high 32 bits
aoqi@1 4348 __ dsrl32(AT, AT, 0);
aoqi@1 4349 __ dsrlv(dest_reg, AT, count_reg); // Unsigned right shift
aoqi@1 4350 break;
aoqi@1 4351 }
aoqi@1 4352 #endif
aoqi@1 4353 __ dsrlv(dest_reg, value_reg, count_reg); break;
aoqi@1 4354 default: ShouldNotReachHere();
aoqi@1 4355 }
aoqi@1 4356 #else
aoqi@1 4357 if (left->is_single_cpu()) {
aoqi@1 4358 Register value_reg = left->as_register();
aoqi@1 4359 Register count_reg = count->as_register();
aoqi@1 4360 Register dest_reg = dest->as_register();
aoqi@1 4361 assert_different_registers(count_reg, value_reg);
aoqi@1 4362
aoqi@1 4363 switch (code) {
aoqi@1 4364 case lir_shl: __ sllv(dest_reg, value_reg, count_reg); break;
aoqi@1 4365 case lir_shr: __ srav(dest_reg, value_reg, count_reg); break;
aoqi@1 4366 case lir_ushr: __ srlv(dest_reg, value_reg, count_reg); break;
aoqi@1 4367 default: ShouldNotReachHere();
aoqi@1 4368 }
aoqi@1 4369
aoqi@1 4370 } else if (left->is_double_cpu()) {
aoqi@1 4371 Register creg = count->as_register();
aoqi@1 4372 Register lo = left->as_register_lo();
aoqi@1 4373 Register hi = left->as_register_hi();
aoqi@1 4374 Register dlo = dest->as_register_lo();
aoqi@1 4375 Register dhi = dest->as_register_hi();
aoqi@1 4376
aoqi@1 4377 __ andi(creg, creg, 0x3f);
aoqi@1 4378 switch (code) {
aoqi@1 4379 case lir_shl:
aoqi@1 4380 {
aoqi@1 4381 Label normal, done, notzero;
aoqi@1 4382
aoqi@1 4383 //count=0
aoqi@1 4384 __ bne(creg, R0, notzero);
aoqi@1 4385 __ delayed()->nop();
aoqi@1 4386 __ move(dlo, lo);
aoqi@1 4387 __ b(done);
aoqi@1 4388 __ delayed();
aoqi@1 4389 __ move(dhi, hi);
aoqi@1 4390
aoqi@1 4391 //count>=32
aoqi@1 4392 __ bind(notzero);
aoqi@1 4393 __ sltiu(AT, creg, BitsPerWord);
aoqi@1 4394 __ bne(AT, R0, normal);
aoqi@1 4395 __ delayed();
aoqi@1 4396 __ addiu(AT, creg, (-1) * BitsPerWord);
aoqi@1 4397 __ sllv(dhi, lo, AT);
aoqi@1 4398 __ b(done);
aoqi@1 4399 __ delayed();
aoqi@1 4400 __ move(dlo, R0);
aoqi@1 4401
aoqi@1 4402 //count<32
aoqi@1 4403 __ bind(normal);
aoqi@1 4404 __ sllv(dhi, hi, creg);
aoqi@1 4405 __ move(AT, BitsPerWord);
aoqi@1 4406 __ sub(AT, AT, creg);
aoqi@1 4407 __ srlv(AT, lo, AT);
aoqi@1 4408 __ orr(dhi, dhi, AT);
aoqi@1 4409 __ sllv(dlo, lo, creg);
aoqi@1 4410 __ bind(done);
aoqi@1 4411 }
aoqi@1 4412 break;
aoqi@1 4413 case lir_shr:
aoqi@1 4414 {
aoqi@1 4415 Label normal, done, notzero;
aoqi@1 4416
aoqi@1 4417 //count=0
aoqi@1 4418 __ bne(creg, R0, notzero);
aoqi@1 4419 __ delayed()->nop();
aoqi@1 4420 __ move(dhi, hi);
aoqi@1 4421 __ b(done);
aoqi@1 4422 __ delayed();
aoqi@1 4423 __ move(dlo, lo);
aoqi@1 4424
aoqi@1 4425 //count>=32
aoqi@1 4426 __ bind(notzero);
aoqi@1 4427 __ sltiu(AT, creg, BitsPerWord);
aoqi@1 4428 __ bne(AT, R0, normal);
aoqi@1 4429 __ delayed();
aoqi@1 4430 __ addiu(AT, creg, (-1) * BitsPerWord);
aoqi@1 4431 __ srav(dlo, hi, AT);
aoqi@1 4432 __ b(done);
aoqi@1 4433 __ delayed();
aoqi@1 4434 __ sra(dhi, hi, BitsPerWord - 1);
aoqi@1 4435
aoqi@1 4436 //count<32
aoqi@1 4437 __ bind(normal);
aoqi@1 4438 __ srlv(dlo, lo, creg);
aoqi@1 4439 __ move(AT, BitsPerWord);
aoqi@1 4440 __ sub(AT, AT, creg);
aoqi@1 4441 __ sllv(AT, hi, AT);
aoqi@1 4442 __ orr(dlo, dlo, AT);
aoqi@1 4443 __ srav(dhi, hi, creg);
aoqi@1 4444 __ bind(done);
aoqi@1 4445 }
aoqi@1 4446 break;
aoqi@1 4447 case lir_ushr:
aoqi@1 4448 {
aoqi@1 4449 Label normal, done, notzero;
aoqi@1 4450
aoqi@1 4451 //count=zero
aoqi@1 4452 __ bne(creg, R0, notzero);
aoqi@1 4453 __ delayed()->nop();
aoqi@1 4454 __ move(dhi, hi);
aoqi@1 4455 __ b(done);
aoqi@1 4456 __ delayed();
aoqi@1 4457 __ move(dlo, lo);
aoqi@1 4458
aoqi@1 4459 //count>=32
aoqi@1 4460 __ bind(notzero);
aoqi@1 4461 __ sltiu(AT, creg, BitsPerWord);
aoqi@1 4462 __ bne(AT, R0, normal);
aoqi@1 4463 __ delayed();
aoqi@1 4464 __ addi(AT, creg, (-1) * BitsPerWord);
aoqi@1 4465 __ srlv(dlo, hi, AT);
aoqi@1 4466 __ b(done);
aoqi@1 4467 __ delayed();
aoqi@1 4468 __ move(dhi, R0);
aoqi@1 4469
aoqi@1 4470 //count<32
aoqi@1 4471 __ bind(normal);
aoqi@1 4472 __ srlv(dlo, lo, creg);
aoqi@1 4473 __ move(AT, BitsPerWord);
aoqi@1 4474 __ sub(AT, AT, creg);
aoqi@1 4475 __ sllv(AT, hi, AT);
aoqi@1 4476 __ orr(dlo, dlo, AT);
aoqi@1 4477 __ srlv(dhi, hi, creg);
aoqi@1 4478 __ bind(done);
aoqi@1 4479 }
aoqi@1 4480 break;
aoqi@1 4481 default: ShouldNotReachHere();
aoqi@1 4482 }
aoqi@1 4483 } else {
aoqi@1 4484 ShouldNotReachHere();
aoqi@1 4485 }
aoqi@1 4486 #endif
aoqi@1 4487
aoqi@1 4488 }
aoqi@1 4489
aoqi@1 4490 void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, jint count, LIR_Opr dest) {
aoqi@1 4491 if (dest->is_single_cpu()) {
aoqi@1 4492 /* In WebClient,
aoqi@1 4493 * virtual jboolean java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl.compareAndSet
aoqi@1 4494 *
aoqi@1 4495 * 130 ushift_right [a4a4|J] [int:9|I] [a4|L]
aoqi@1 4496 */
aoqi@1 4497 Register value_reg = left->is_single_cpu() ? left->as_register() : left->as_register_lo();
aoqi@1 4498 Register dest_reg = dest->as_register();
aoqi@1 4499 count = count & 0x1F; // Java spec
aoqi@1 4500
aoqi@1 4501 switch (code) {
aoqi@1 4502 #ifdef _LP64
aoqi@1 4503 case lir_shl:
aoqi@1 4504 if (dest->type() == T_INT)
aoqi@1 4505 __ sll(dest_reg, value_reg, count);
aoqi@1 4506 else
aoqi@1 4507 __ dsll(dest_reg, value_reg, count);
aoqi@1 4508 break;
aoqi@1 4509 case lir_shr: __ dsra(dest_reg, value_reg, count); break;
aoqi@1 4510 case lir_ushr:
aoqi@1 4511 #if 1
aoqi@1 4512 if (left->type() == T_INT && dest->type() == T_INT)
aoqi@1 4513 {
aoqi@1 4514 /* Jin: in java, ushift_right requires 32-bit UNSIGNED operation!
aoqi@1 4515 However, dsrl will shift in company with the highest 32 bits.
aoqi@1 4516 Thus, if the source register contains a negative value,
aoqi@1 4517 the resulti is incorrect.
aoqi@1 4518
aoqi@1 4519 Example: in java.util.HashMap.get()
aoqi@1 4520
aoqi@1 4521 68 ushift_right [t0|I] [int:20|I] [a4|I]
aoqi@1 4522 dsrl a4, t0, 20
aoqi@1 4523
aoqi@1 4524 t0: 0xFFFFFFFF87654321 (64bits for 0x87654321)
aoqi@1 4525
aoqi@1 4526 ushift_right t0, 16 -> a4
aoqi@1 4527
aoqi@1 4528 a4: 00000000 00008765 (right)
aoqi@1 4529 a4: FFFFFFFF FFFF8765 (wrong)
aoqi@1 4530 */
aoqi@1 4531 __ dsll32(dest_reg, value_reg, 0); // Omit the high 32 bits
aoqi@1 4532 __ dsrl32(dest_reg, dest_reg, count); // Unsigned right shift
aoqi@1 4533 break;
aoqi@1 4534 }
aoqi@1 4535 #endif
aoqi@1 4536
aoqi@1 4537 __ dsrl(dest_reg, value_reg, count);
aoqi@1 4538 break;
aoqi@1 4539 #else
aoqi@1 4540 case lir_shl: __ sll(dest_reg, value_reg, count); break;
aoqi@1 4541 case lir_shr: __ sra(dest_reg, value_reg, count); break;
aoqi@1 4542 case lir_ushr: __ srl(dest_reg, value_reg, count); break;
aoqi@1 4543 #endif
aoqi@1 4544 default: ShouldNotReachHere();
aoqi@1 4545 }
aoqi@1 4546
aoqi@1 4547 } else if (dest->is_double_cpu()) {
aoqi@1 4548 Register valuelo = left->is_single_cpu() ? left->as_register() : left->as_register_lo();
aoqi@1 4549 Register destlo = dest->as_register_lo();
aoqi@1 4550 count = count & 0x3f;
aoqi@1 4551 #ifdef _LP64
aoqi@1 4552 switch (code) {
aoqi@1 4553 case lir_shl: __ dsll(destlo, valuelo, count); break;
aoqi@1 4554 case lir_shr: __ dsra(destlo, valuelo, count); break;
aoqi@1 4555 case lir_ushr: __ dsrl(destlo, valuelo, count); break;
aoqi@1 4556 default: ShouldNotReachHere();
aoqi@1 4557 }
aoqi@1 4558 #else
aoqi@1 4559 Register desthi = dest->as_register_hi();
aoqi@1 4560 Register valuehi = left->as_register_hi();
aoqi@1 4561 assert_different_registers(destlo, valuehi, desthi);
aoqi@1 4562 switch (code) {
aoqi@1 4563 case lir_shl:
aoqi@1 4564 if (count==0) {
aoqi@1 4565 __ move(destlo, valuelo);
aoqi@1 4566 __ move(desthi, valuehi);
aoqi@1 4567 } else if (count>=32) {
aoqi@1 4568 __ sll(desthi, valuelo, count-32);
aoqi@1 4569 __ move(destlo, R0);
aoqi@1 4570 } else {
aoqi@1 4571 __ srl(AT, valuelo, 32 - count);
aoqi@1 4572 __ sll(destlo, valuelo, count);
aoqi@1 4573 __ sll(desthi, valuehi, count);
aoqi@1 4574 __ orr(desthi, desthi, AT);
aoqi@1 4575 }
aoqi@1 4576 break;
aoqi@1 4577
aoqi@1 4578 case lir_shr:
aoqi@1 4579 if (count==0) {
aoqi@1 4580 __ move(destlo, valuelo);
aoqi@1 4581 __ move(desthi, valuehi);
aoqi@1 4582 } else if (count>=32) {
aoqi@1 4583 __ sra(destlo, valuehi, count-32);
aoqi@1 4584 __ sra(desthi, valuehi, 31);
aoqi@1 4585 } else {
aoqi@1 4586 __ sll(AT, valuehi, 32 - count);
aoqi@1 4587 __ sra(desthi, valuehi, count);
aoqi@1 4588 __ srl(destlo, valuelo, count);
aoqi@1 4589 __ orr(destlo, destlo, AT);
aoqi@1 4590 }
aoqi@1 4591 break;
aoqi@1 4592
aoqi@1 4593 case lir_ushr:
aoqi@1 4594 if (count==0) {
aoqi@1 4595 __ move(destlo, valuelo);
aoqi@1 4596 __ move(desthi, valuehi);
aoqi@1 4597 } else if (count>=32) {
aoqi@1 4598 __ sra(destlo, valuehi, count-32);
aoqi@1 4599 __ move(desthi, R0);
aoqi@1 4600 } else {
aoqi@1 4601 __ sll(AT, valuehi, 32 - count);
aoqi@1 4602 __ srl(desthi, valuehi, count);
aoqi@1 4603 __ srl(destlo, valuelo, count);
aoqi@1 4604 __ orr(destlo, destlo, AT);
aoqi@1 4605 }
aoqi@1 4606 break;
aoqi@1 4607
aoqi@1 4608 default: ShouldNotReachHere();
aoqi@1 4609 }
aoqi@1 4610 #endif
aoqi@1 4611 } else {
aoqi@1 4612 ShouldNotReachHere();
aoqi@1 4613 }
aoqi@1 4614 }
aoqi@1 4615
aoqi@1 4616 void LIR_Assembler::store_parameter(Register r, int offset_from_esp_in_words) {
aoqi@1 4617 assert(offset_from_esp_in_words >= 0, "invalid offset from esp");
aoqi@1 4618 int offset_from_sp_in_bytes = offset_from_esp_in_words * BytesPerWord;
aoqi@1 4619 assert(offset_from_esp_in_words < frame_map()->reserved_argument_area_size(), "invalid offset");
aoqi@1 4620 __ st_ptr(r, SP, offset_from_sp_in_bytes);
aoqi@1 4621 }
aoqi@1 4622
aoqi@1 4623
aoqi@1 4624 void LIR_Assembler::store_parameter(jint c, int offset_from_esp_in_words) {
aoqi@1 4625 assert(offset_from_esp_in_words >= 0, "invalid offset from esp");
aoqi@1 4626 int offset_from_sp_in_bytes = offset_from_esp_in_words * BytesPerWord;
aoqi@1 4627 assert(offset_from_esp_in_words < frame_map()->reserved_argument_area_size(), "invalid offset");
aoqi@1 4628 __ move(AT, c);
aoqi@1 4629 __ st_ptr(AT, SP, offset_from_sp_in_bytes);
aoqi@1 4630 }
aoqi@1 4631
aoqi@1 4632 void LIR_Assembler::store_parameter(jobject o, int offset_from_esp_in_words) {
aoqi@1 4633 assert(offset_from_esp_in_words >= 0, "invalid offset from esp");
aoqi@1 4634 int offset_from_sp_in_bytes = offset_from_esp_in_words * BytesPerWord;
aoqi@1 4635 assert(offset_from_sp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset");
aoqi@1 4636 int oop_index = __ oop_recorder()->find_index(o);
aoqi@1 4637 RelocationHolder rspec = oop_Relocation::spec(oop_index);
aoqi@1 4638 __ relocate(rspec);
aoqi@1 4639 #ifndef _LP64
aoqi@1 4640 //by_css
aoqi@1 4641 __ lui(AT, Assembler::split_high((int)o));
aoqi@1 4642 __ addiu(AT, AT, Assembler::split_low((int)o));
aoqi@1 4643 #else
aoqi@1 4644 __ li48(AT, (long)o);
aoqi@1 4645 #endif
aoqi@1 4646
aoqi@1 4647 __ st_ptr(AT, SP, offset_from_sp_in_bytes);
aoqi@1 4648
aoqi@1 4649 }
aoqi@1 4650
aoqi@1 4651
aoqi@1 4652 // This code replaces a call to arraycopy; no exception may
aoqi@1 4653 // be thrown in this code, they must be thrown in the System.arraycopy
aoqi@1 4654 // activation frame; we could save some checks if this would not be the case
aoqi@1 4655 void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
aoqi@1 4656
aoqi@1 4657
aoqi@1 4658 ciArrayKlass* default_type = op->expected_type();
aoqi@1 4659 Register src = op->src()->as_register();
aoqi@1 4660 Register dst = op->dst()->as_register();
aoqi@1 4661 Register src_pos = op->src_pos()->as_register();
aoqi@1 4662 Register dst_pos = op->dst_pos()->as_register();
aoqi@1 4663 Register length = op->length()->as_register();
aoqi@1 4664 Register tmp = T8;
aoqi@1 4665 #ifndef OPT_THREAD
aoqi@1 4666 Register java_thread = T8;
aoqi@1 4667 #else
aoqi@1 4668 Register java_thread = TREG;
aoqi@1 4669 #endif
aoqi@1 4670 CodeStub* stub = op->stub();
aoqi@1 4671
aoqi@1 4672 int flags = op->flags();
aoqi@1 4673 BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL;
aoqi@1 4674 if (basic_type == T_ARRAY) basic_type = T_OBJECT;
aoqi@1 4675
aoqi@1 4676 // if we don't know anything or it's an object array, just go through the generic arraycopy
aoqi@1 4677 if (default_type == NULL) {
aoqi@1 4678 Label done;
aoqi@1 4679 // save outgoing arguments on stack in case call to System.arraycopy is needed
aoqi@1 4680 // HACK ALERT. This code used to push the parameters in a hardwired fashion
aoqi@1 4681 // for interpreter calling conventions. Now we have to do it in new style conventions.
aoqi@1 4682 // For the moment until C1 gets the new register allocator I just force all the
aoqi@1 4683 // args to the right place (except the register args) and then on the back side
aoqi@1 4684 // reload the register args properly if we go slow path. Yuck
aoqi@1 4685
aoqi@1 4686 // this is saved in the caller's reserved argument area
aoqi@1 4687 //FIXME, maybe It will change something in the stack;
aoqi@1 4688 // These are proper for the calling convention
aoqi@1 4689 //store_parameter(length, 2);
aoqi@1 4690 //store_parameter(dst_pos, 1);
aoqi@1 4691 //store_parameter(dst, 0);
aoqi@1 4692
aoqi@1 4693 // these are just temporary placements until we need to reload
aoqi@1 4694 //store_parameter(src_pos, 3);
aoqi@1 4695 //store_parameter(src, 4);
aoqi@1 4696 assert(src == T0 && src_pos == A0, "mismatch in calling convention");
aoqi@1 4697 // pass arguments: may push as this is not a safepoint; SP must be fix at each safepoint
aoqi@1 4698
aoqi@1 4699 __ push(src);
aoqi@1 4700 __ push(dst);
aoqi@1 4701 __ push(src_pos);
aoqi@1 4702 __ push(dst_pos);
aoqi@1 4703 __ push(length);
aoqi@1 4704
aoqi@1 4705
aoqi@1 4706 // save SP and align
aoqi@1 4707 #ifndef OPT_THREAD
aoqi@1 4708 __ get_thread(java_thread);
aoqi@1 4709 #endif
aoqi@1 4710 __ st_ptr(SP, java_thread, in_bytes(JavaThread::last_Java_sp_offset()));
aoqi@1 4711 #ifndef _LP64
aoqi@1 4712 __ addi(SP, SP, (-5) * wordSize);
aoqi@1 4713 __ move(AT, -(StackAlignmentInBytes));
aoqi@1 4714 __ andr(SP, SP, AT);
aoqi@1 4715 // push argument
aoqi@1 4716 __ sw(length, SP, 4 * wordSize);
aoqi@1 4717 #else
aoqi@1 4718 __ move(A4, length);
aoqi@1 4719 #endif
aoqi@1 4720 __ move(A3, dst_pos);
aoqi@1 4721 __ move(A2, dst);
aoqi@1 4722 __ move(A1, src_pos);
aoqi@1 4723 __ move(A0, src);
aoqi@1 4724 // make call
aoqi@1 4725 address entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy);
aoqi@1 4726 __ call(entry, relocInfo::runtime_call_type);
aoqi@1 4727 __ delayed()->nop();
aoqi@1 4728 // restore SP
aoqi@1 4729 #ifndef OPT_THREAD
aoqi@1 4730 __ get_thread(java_thread);
aoqi@1 4731 #endif
aoqi@1 4732 __ ld_ptr(SP, java_thread, in_bytes(JavaThread::last_Java_sp_offset()));
aoqi@1 4733 __ super_pop(length);
aoqi@1 4734 __ super_pop(dst_pos);
aoqi@1 4735 __ super_pop(src_pos);
aoqi@1 4736 __ super_pop(dst);
aoqi@1 4737 __ super_pop(src);
aoqi@1 4738
aoqi@1 4739 __ beq_far(V0, R0, *stub->continuation());
aoqi@1 4740 __ delayed()->nop();
aoqi@1 4741
aoqi@1 4742
aoqi@1 4743 __ b_far(*stub->entry());
aoqi@1 4744 __ delayed()->nop();
aoqi@1 4745 __ bind(*stub->continuation());
aoqi@1 4746 return;
aoqi@1 4747 }
aoqi@1 4748 assert(default_type != NULL
aoqi@1 4749 && default_type->is_array_klass()
aoqi@1 4750 && default_type->is_loaded(),
aoqi@1 4751 "must be true at this point");
aoqi@1 4752
aoqi@1 4753 int elem_size = type2aelembytes(basic_type);
aoqi@1 4754 int shift_amount;
aoqi@1 4755 switch (elem_size) {
aoqi@1 4756 case 1 :shift_amount = 0; break;
aoqi@1 4757 case 2 :shift_amount = 1; break;
aoqi@1 4758 case 4 :shift_amount = 2; break;
aoqi@1 4759 case 8 :shift_amount = 3; break;
aoqi@1 4760 default:ShouldNotReachHere();
aoqi@1 4761 }
aoqi@1 4762
aoqi@1 4763 Address src_length_addr = Address(src, arrayOopDesc::length_offset_in_bytes());
aoqi@1 4764 Address dst_length_addr = Address(dst, arrayOopDesc::length_offset_in_bytes());
aoqi@1 4765 Address src_klass_addr = Address(src, oopDesc::klass_offset_in_bytes());
aoqi@1 4766 Address dst_klass_addr = Address(dst, oopDesc::klass_offset_in_bytes());
aoqi@1 4767
aoqi@1 4768 // test for NULL
aoqi@1 4769 if (flags & LIR_OpArrayCopy::src_null_check) {
aoqi@1 4770 __ beq_far(src, R0, *stub->entry());
aoqi@1 4771 __ delayed()->nop();
aoqi@1 4772 }
aoqi@1 4773 if (flags & LIR_OpArrayCopy::dst_null_check) {
aoqi@1 4774 __ beq_far(dst, R0, *stub->entry());
aoqi@1 4775 __ delayed()->nop();
aoqi@1 4776 }
aoqi@1 4777
aoqi@1 4778 // check if negative
aoqi@1 4779 if (flags & LIR_OpArrayCopy::src_pos_positive_check) {
aoqi@1 4780 __ bltz(src_pos, *stub->entry());
aoqi@1 4781 __ delayed()->nop();
aoqi@1 4782 }
aoqi@1 4783 if (flags & LIR_OpArrayCopy::dst_pos_positive_check) {
aoqi@1 4784 __ bltz(dst_pos, *stub->entry());
aoqi@1 4785 __ delayed()->nop();
aoqi@1 4786 }
aoqi@1 4787 if (flags & LIR_OpArrayCopy::length_positive_check) {
aoqi@1 4788 __ bltz(length, *stub->entry());
aoqi@1 4789 __ delayed()->nop();
aoqi@1 4790 }
aoqi@1 4791
aoqi@1 4792 if (flags & LIR_OpArrayCopy::src_range_check) {
aoqi@1 4793 __ add(AT, src_pos, length);
aoqi@1 4794 __ lw(tmp, src_length_addr);
aoqi@1 4795 __ sltu(AT, tmp, AT);
aoqi@1 4796 __ bne_far(AT, R0, *stub->entry());
aoqi@1 4797 __ delayed()->nop();
aoqi@1 4798 }
aoqi@1 4799 if (flags & LIR_OpArrayCopy::dst_range_check) {
aoqi@1 4800 __ add(AT, dst_pos, length);
aoqi@1 4801 __ lw(tmp, dst_length_addr);
aoqi@1 4802 __ sltu(AT, tmp, AT);
aoqi@1 4803 __ bne_far(AT, R0, *stub->entry());
aoqi@1 4804 __ delayed()->nop();
aoqi@1 4805 }
aoqi@1 4806
aoqi@1 4807 if (flags & LIR_OpArrayCopy::type_check) {
aoqi@1 4808 if (UseCompressedOops) {
aoqi@1 4809 __ lw(AT, src_klass_addr);
aoqi@1 4810 __ lw(tmp, dst_klass_addr);
aoqi@1 4811 } else {
aoqi@1 4812 __ ld(AT, src_klass_addr);
aoqi@1 4813 __ ld(tmp, dst_klass_addr);
aoqi@1 4814 }
aoqi@1 4815 __ bne_far(AT, tmp, *stub->entry());
aoqi@1 4816 __ delayed()->nop();
aoqi@1 4817 }
aoqi@1 4818
aoqi@1 4819 #ifdef ASSERT
aoqi@1 4820 if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) {
aoqi@1 4821 // Sanity check the known type with the incoming class. For the
aoqi@1 4822 // primitive case the types must match exactly. For the object array
aoqi@1 4823 // case, if no type check is needed then the dst type must match the
aoqi@1 4824 // expected type and the src type is so subtype which we can't check. If
aoqi@1 4825 // a type check i needed then at this point the classes are known to be
aoqi@1 4826 // the same but again which don't know which type so we can't check them.
aoqi@1 4827 Label known_ok, halt;
aoqi@1 4828 //FIXME:wuhui. not finished. __ mov_metadata(tmp, default_type->constant_encoding());
aoqi@1 4829 #ifdef _LP64
aoqi@1 4830 if (UseCompressedOops) {
aoqi@1 4831 __ encode_heap_oop(AT);
aoqi@1 4832 __ lw(tmp, dst_klass_addr);
aoqi@1 4833 } else
aoqi@1 4834 #endif
aoqi@1 4835 {
aoqi@1 4836 __ ld(tmp, dst_klass_addr);
aoqi@1 4837 }
aoqi@1 4838 if (basic_type != T_OBJECT) {
aoqi@1 4839 __ bne(AT, tmp, halt);
aoqi@1 4840 __ delayed()->nop();
aoqi@1 4841 if (UseCompressedOops) {
aoqi@1 4842 __ lw(tmp, src_klass_addr);
aoqi@1 4843 } else {
aoqi@1 4844 __ ld(tmp, src_klass_addr);
aoqi@1 4845 }
aoqi@1 4846 __ beq(AT, tmp, known_ok);
aoqi@1 4847 __ delayed()->nop();
aoqi@1 4848 } else {
aoqi@1 4849 if (UseCompressedOops) {
aoqi@1 4850 __ lw(tmp, dst_klass_addr);
aoqi@1 4851 } else {
aoqi@1 4852 __ ld(tmp, dst_klass_addr);
aoqi@1 4853 }
aoqi@1 4854 __ beq(AT, tmp, known_ok);
aoqi@1 4855 __ delayed()->nop();
aoqi@1 4856 __ beq(src, dst, known_ok);
aoqi@1 4857 __ delayed()->nop();
aoqi@1 4858 }
aoqi@1 4859 __ bind(halt);
aoqi@1 4860 __ stop("incorrect type information in arraycopy");
aoqi@1 4861 __ bind(known_ok);
aoqi@1 4862 }
aoqi@1 4863 #endif
aoqi@1 4864 __ push(src);
aoqi@1 4865 __ push(dst);
aoqi@1 4866 __ push(src_pos);
aoqi@1 4867 __ push(dst_pos);
aoqi@1 4868 __ push(length);
aoqi@1 4869
aoqi@1 4870
aoqi@1 4871 assert(A0 != A1 &&
aoqi@1 4872 A0 != length &&
aoqi@1 4873 A1 != length, "register checks");
aoqi@1 4874 __ move(AT, dst_pos);
aoqi@1 4875 if (shift_amount > 0 && basic_type != T_OBJECT) {
aoqi@1 4876 #ifndef _LP64
aoqi@1 4877 __ sll(A2, length, shift_amount);
aoqi@1 4878 #else
aoqi@1 4879 __ dsll(A2, length, shift_amount);
aoqi@1 4880 #endif
aoqi@1 4881 } else {
aoqi@1 4882 if (length!=A2)
aoqi@1 4883 __ move(A2, length);
aoqi@1 4884 }
aoqi@1 4885 __ move(A3, src_pos );
aoqi@1 4886 assert(A0 != dst_pos &&
aoqi@1 4887 A0 != dst &&
aoqi@1 4888 dst_pos != dst, "register checks");
aoqi@1 4889
aoqi@1 4890 assert_different_registers(A0, dst_pos, dst);
aoqi@1 4891 #ifndef _LP64
aoqi@1 4892 __ sll(AT, AT, shift_amount);
aoqi@1 4893 #else
aoqi@1 4894 __ dsll(AT, AT, shift_amount);
aoqi@1 4895 #endif
aoqi@1 4896 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(basic_type));
aoqi@1 4897 __ add(A1, dst, AT);
aoqi@1 4898
aoqi@1 4899 #ifndef _LP64
aoqi@1 4900 __ sll(AT, A3, shift_amount);
aoqi@1 4901 #else
aoqi@1 4902 __ dsll(AT, A3, shift_amount);
aoqi@1 4903 #endif
aoqi@1 4904 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(basic_type));
aoqi@1 4905 __ add(A0, src, AT);
aoqi@1 4906
aoqi@1 4907
aoqi@1 4908
aoqi@1 4909 if (basic_type == T_OBJECT) {
aoqi@1 4910 __ call_VM_leaf(CAST_FROM_FN_PTR(address, Runtime1::oop_arraycopy), 3);
aoqi@1 4911 } else {
aoqi@1 4912 __ call_VM_leaf(CAST_FROM_FN_PTR(address, Runtime1::primitive_arraycopy), 3);
aoqi@1 4913 }
aoqi@1 4914 __ super_pop(length);
aoqi@1 4915 __ super_pop(dst_pos);
aoqi@1 4916 __ super_pop(src_pos);
aoqi@1 4917 __ super_pop(dst);
aoqi@1 4918 __ super_pop(src);
aoqi@1 4919
aoqi@1 4920 __ bind(*stub->continuation());
aoqi@1 4921 }
aoqi@1 4922
aoqi@1 4923 void LIR_Assembler::emit_updatecrc32(LIR_OpUpdateCRC32* op) {
aoqi@1 4924 tty->print_cr("LIR_Assembler::emit_updatecrc32 unimplemented yet !");
aoqi@1 4925 Unimplemented();
aoqi@1 4926 }
aoqi@1 4927
aoqi@1 4928 void LIR_Assembler::emit_lock(LIR_OpLock* op) {
aoqi@1 4929 Register obj = op->obj_opr()->as_register(); // may not be an oop
aoqi@1 4930 Register hdr = op->hdr_opr()->as_register();
aoqi@1 4931 Register lock = op->lock_opr()->is_single_cpu() ? op->lock_opr()->as_register(): op->lock_opr()->as_register_lo();
aoqi@1 4932 if (!UseFastLocking) {
aoqi@1 4933 __ b_far(*op->stub()->entry());
aoqi@1 4934 } else if (op->code() == lir_lock) {
aoqi@1 4935 Register scratch = noreg;
aoqi@1 4936 if (UseBiasedLocking) {
aoqi@1 4937 scratch = op->scratch_opr()->as_register();
aoqi@1 4938 }
aoqi@1 4939 assert(BasicLock::displaced_header_offset_in_bytes() == 0,
aoqi@1 4940 "lock_reg must point to the displaced header");
aoqi@1 4941 // add debug info for NullPointerException only if one is possible
aoqi@1 4942 int null_check_offset = __ lock_object(hdr, obj, lock, scratch, *op->stub()->entry());
aoqi@1 4943 if (op->info() != NULL) {
aoqi@1 4944 //add_debug_info_for_null_check_here(op->info());
aoqi@1 4945 add_debug_info_for_null_check(null_check_offset,op->info());
aoqi@1 4946 }
aoqi@1 4947 // done
aoqi@1 4948 } else if (op->code() == lir_unlock) {
aoqi@1 4949 assert(BasicLock::displaced_header_offset_in_bytes() == 0,
aoqi@1 4950 "lock_reg must point to the displaced header");
aoqi@1 4951 __ unlock_object(hdr, obj, lock, *op->stub()->entry());
aoqi@1 4952 } else {
aoqi@1 4953 Unimplemented();
aoqi@1 4954 }
aoqi@1 4955 __ bind(*op->stub()->continuation());
aoqi@1 4956 }
aoqi@1 4957
aoqi@1 4958
aoqi@1 4959
aoqi@1 4960 void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
aoqi@1 4961 ciMethod* method = op->profiled_method();
aoqi@1 4962 int bci = op->profiled_bci();
aoqi@1 4963 ciMethod* callee = op->profiled_callee();
aoqi@1 4964 // Update counter for all call types
aoqi@1 4965 ciMethodData* md = method->method_data();
aoqi@1 4966 if (md == NULL) {
aoqi@1 4967 bailout("out of memory building methodDataOop");
aoqi@1 4968 return;
aoqi@1 4969 }
aoqi@1 4970 ciProfileData* data = md->bci_to_data(bci);
aoqi@1 4971 assert(data->is_CounterData(), "need CounterData for calls");
aoqi@1 4972 assert(op->mdo()->is_single_cpu(), "mdo must be allocated");
aoqi@1 4973 Register mdo = op->mdo()->as_register();
aoqi@1 4974
aoqi@1 4975 int oop_index = __ oop_recorder()->find_index(md->constant_encoding());
aoqi@1 4976 RelocationHolder rspec = oop_Relocation::spec(oop_index);
aoqi@1 4977 __ relocate(rspec);
aoqi@1 4978 #ifndef _LP64
aoqi@1 4979 //by_css
aoqi@1 4980 __ lui(mdo, Assembler::split_high((int)md->constant_encoding()));
aoqi@1 4981 __ addiu(mdo, mdo, Assembler::split_low((int)md->constant_encoding()));
aoqi@1 4982 #else
aoqi@1 4983 __ li48(mdo, (long)md->constant_encoding());
aoqi@1 4984 #endif
aoqi@1 4985
aoqi@1 4986 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
aoqi@1 4987 __ lw(AT, counter_addr);
aoqi@1 4988 __ addi(AT,AT, DataLayout::counter_increment);
aoqi@1 4989 __ sw(AT,counter_addr);
aoqi@1 4990
aoqi@1 4991 Bytecodes::Code bc = method->java_code_at_bci(bci);
aoqi@1 4992 const bool callee_is_static = callee->is_loaded() && callee->is_static();
aoqi@1 4993 // Perform additional virtual call profiling for invokevirtual and
aoqi@1 4994 // invokeinterface bytecodes
aoqi@1 4995 if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) &&
aoqi@1 4996 !callee_is_static && //required for optimized MH invokes
aoqi@1 4997 C1ProfileVirtualCalls) {
aoqi@1 4998 assert(op->recv()->is_single_cpu(), "recv must be allocated");
aoqi@1 4999 Register recv = op->recv()->as_register();
aoqi@1 5000 assert_different_registers(mdo, recv);
aoqi@1 5001 assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls");
aoqi@1 5002 ciKlass* known_klass = op->known_holder();
aoqi@1 5003 if (C1OptimizeVirtualCallProfiling && known_klass != NULL) {
aoqi@1 5004 // We know the type that will be seen at this call site; we can
aoqi@1 5005 // statically update the methodDataOop rather than needing to do
aoqi@1 5006 // dynamic tests on the receiver type
aoqi@1 5007
aoqi@1 5008 // NOTE: we should probably put a lock around this search to
aoqi@1 5009 // avoid collisions by concurrent compilations
aoqi@1 5010 ciVirtualCallData* vc_data = (ciVirtualCallData*) data;
aoqi@1 5011 uint i;
aoqi@1 5012 for (i = 0; i < VirtualCallData::row_limit(); i++) {
aoqi@1 5013 ciKlass* receiver = vc_data->receiver(i);
aoqi@1 5014 if (known_klass->equals(receiver)) {
aoqi@1 5015 Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
aoqi@1 5016 __ lw(AT, data_addr);
aoqi@1 5017 __ addi(AT, AT, DataLayout::counter_increment);
aoqi@1 5018 __ sw(AT, data_addr);
aoqi@1 5019 return;
aoqi@1 5020 }
aoqi@1 5021 }
aoqi@1 5022
aoqi@1 5023 // Receiver type not found in profile data; select an empty slot
aoqi@1 5024
aoqi@1 5025 // Note that this is less efficient than it should be because it
aoqi@1 5026 // always does a write to the receiver part of the
aoqi@1 5027 // VirtualCallData rather than just the first time
aoqi@1 5028 for (i = 0; i < VirtualCallData::row_limit(); i++) {
aoqi@1 5029 ciKlass* receiver = vc_data->receiver(i);
aoqi@1 5030 if (receiver == NULL) {
aoqi@1 5031 Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)));
aoqi@1 5032 int oop_index = __ oop_recorder()->find_index(known_klass->constant_encoding());
aoqi@1 5033 RelocationHolder rspec = oop_Relocation::spec(oop_index);
aoqi@1 5034 __ relocate(rspec);
aoqi@1 5035 #ifndef _LP64
aoqi@1 5036 //by_css
aoqi@1 5037 __ lui(AT, Assembler::split_high((int)known_klass->constant_encoding()));
aoqi@1 5038 __ addiu(AT, AT, Assembler::split_low((int)known_klass->constant_encoding()));
aoqi@1 5039 #else
aoqi@1 5040 __ li48(AT, (long)known_klass->constant_encoding());
aoqi@1 5041 #endif
aoqi@1 5042 __ st_ptr(AT,recv_addr);
aoqi@1 5043 Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
aoqi@1 5044 __ lw(AT, data_addr);
aoqi@1 5045 __ addi(AT, AT, DataLayout::counter_increment);
aoqi@1 5046 __ sw(AT, data_addr);
aoqi@1 5047 return;
aoqi@1 5048 }
aoqi@1 5049 }
aoqi@1 5050 } else {
aoqi@1 5051 //__ ld_ptr(recv, Address(recv, oopDesc::klass_offset_in_bytes()));
aoqi@1 5052 __ load_klass(recv, recv);
aoqi@1 5053 Label update_done;
aoqi@1 5054 uint i;
aoqi@1 5055 for (i = 0; i < VirtualCallData::row_limit(); i++) {
aoqi@1 5056 Label next_test;
aoqi@1 5057 // See if the receiver is receiver[n].
aoqi@1 5058 __ ld_ptr(AT, Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))));
aoqi@1 5059 __ bne(recv,AT,next_test);
aoqi@1 5060 __ delayed()->nop();
aoqi@1 5061 Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
aoqi@1 5062 __ lw(AT, data_addr);
aoqi@1 5063 __ addi(AT, AT, DataLayout::counter_increment);
aoqi@1 5064 __ sw(AT, data_addr);
aoqi@1 5065 __ b(update_done);
aoqi@1 5066 __ delayed()->nop();
aoqi@1 5067 __ bind(next_test);
aoqi@1 5068 }
aoqi@1 5069
aoqi@1 5070 // Didn't find receiver; find next empty slot and fill it in
aoqi@1 5071 for (i = 0; i < VirtualCallData::row_limit(); i++) {
aoqi@1 5072 Label next_test;
aoqi@1 5073 Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)));
aoqi@1 5074 __ ld_ptr(AT, recv_addr);
aoqi@1 5075 __ bne(AT, R0, next_test);
aoqi@1 5076 __ delayed()->nop();
aoqi@1 5077 __ st_ptr(recv, recv_addr);
aoqi@1 5078 __ move(AT,DataLayout::counter_increment);
aoqi@1 5079 __ sw(AT,Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))));
aoqi@1 5080 if (i < (VirtualCallData::row_limit() - 1)) {
aoqi@1 5081 __ b(update_done);
aoqi@1 5082 __ delayed()->nop();
aoqi@1 5083 }
aoqi@1 5084 __ bind(next_test);
aoqi@1 5085 }
aoqi@1 5086
aoqi@1 5087 __ bind(update_done);
aoqi@1 5088 }
aoqi@1 5089 }
aoqi@1 5090 }
aoqi@1 5091
aoqi@1 5092 void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
aoqi@1 5093 // Newly added in OpenJDK 8
aoqi@1 5094 Unimplemented();
aoqi@1 5095 }
aoqi@1 5096
aoqi@1 5097 void LIR_Assembler::emit_delay(LIR_OpDelay*) {
aoqi@1 5098 Unimplemented();
aoqi@1 5099 }
aoqi@1 5100
aoqi@1 5101
aoqi@1 5102 void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) {
aoqi@1 5103 if (dst->is_single_cpu())
aoqi@1 5104 __ lea(dst->as_register(), frame_map()->address_for_monitor_lock(monitor_no));
aoqi@1 5105 else if (dst->is_double_cpu())
aoqi@1 5106 __ lea(dst->as_register_lo(), frame_map()->address_for_monitor_lock(monitor_no));
aoqi@1 5107 }
aoqi@1 5108
aoqi@1 5109 void LIR_Assembler::align_backward_branch_target() {
aoqi@1 5110 }
aoqi@1 5111
aoqi@1 5112
aoqi@1 5113 void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) {
aoqi@1 5114 if (left->is_single_cpu()) {
aoqi@1 5115 __ subu(dest->as_register(), R0, left->as_register());
aoqi@1 5116 } else if (left->is_double_cpu()) {
aoqi@1 5117 #ifndef _LP64
aoqi@1 5118 Register lo = left->as_register_lo();
aoqi@1 5119 Register hi = left->as_register_hi();
aoqi@1 5120 Register dlo = dest->as_register_lo();
aoqi@1 5121 Register dhi = dest->as_register_hi();
aoqi@1 5122 assert(dlo != hi, "register checks");
aoqi@1 5123 __ nor(dlo, R0, lo);
aoqi@1 5124 __ addiu(dlo, dlo, 1);
aoqi@1 5125 __ sltiu(AT, dlo, 1);
aoqi@1 5126 __ nor(dhi, R0, hi);
aoqi@1 5127 __ addu(dhi, dhi, AT);
aoqi@1 5128 #else
aoqi@1 5129 __ subu(dest->as_register_lo(), R0, left->as_register_lo());
aoqi@1 5130 #endif
aoqi@1 5131 } else if (left->is_single_fpu()) {
aoqi@1 5132 //for mips , does it required ?
aoqi@1 5133 __ neg_s(dest->as_float_reg(), left->as_float_reg());
aoqi@1 5134 } else if (left->is_double_fpu()) {
aoqi@1 5135 //for mips , does it required ?
aoqi@1 5136 __ neg_d(dest->as_double_reg(), left->as_double_reg());
aoqi@1 5137 }else {
aoqi@1 5138 ShouldNotReachHere();
aoqi@1 5139 }
aoqi@1 5140 }
aoqi@1 5141
aoqi@1 5142
aoqi@1 5143 void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest) {
aoqi@1 5144 assert(addr->is_address() && dest->is_register(), "check");
aoqi@1 5145 Register reg = dest->as_register();
aoqi@1 5146 __ lea(dest->as_register(), as_Address(addr->as_address_ptr()));
aoqi@1 5147 }
aoqi@1 5148
aoqi@1 5149
aoqi@1 5150 void LIR_Assembler::jobject2reg(jobject o, Register reg) {
aoqi@1 5151 if (o == NULL) {
aoqi@1 5152 // This seems wrong as we do not emit relocInfo
aoqi@1 5153 // for classes that are not loaded yet, i.e., they will be
aoqi@1 5154 // never GC'd
aoqi@1 5155 #ifndef _LP64
aoqi@1 5156 //by_css
aoqi@1 5157 __ lui(reg, Assembler::split_high((int)o));
aoqi@1 5158 __ addiu(reg, reg, Assembler::split_low((int)o));
aoqi@1 5159 #else
aoqi@1 5160 //__ li48(reg, (long)o);
aoqi@1 5161 __ li(reg, (long)o);
aoqi@1 5162 #endif
aoqi@1 5163 } else {
aoqi@1 5164 int oop_index = __ oop_recorder()->find_index(o);
aoqi@1 5165 RelocationHolder rspec = oop_Relocation::spec(oop_index);
aoqi@1 5166 __ relocate(rspec);
aoqi@1 5167 #ifndef _LP64
aoqi@1 5168 //by_css
aoqi@1 5169 __ lui(reg, Assembler::split_high((int)o));
aoqi@1 5170 __ addiu(reg, reg, Assembler::split_low((int)o));
aoqi@1 5171 #else
aoqi@1 5172 //__ li48(reg, (long)o);
aoqi@1 5173 __ li(reg, (long)o);
aoqi@1 5174 #endif
aoqi@1 5175 }
aoqi@1 5176 }
aoqi@1 5177
aoqi@1 5178 void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info) {
aoqi@1 5179 assert(!tmp->is_valid(), "don't need temporary");
aoqi@1 5180 __ call(dest, relocInfo::runtime_call_type);
aoqi@1 5181 __ delayed()->nop();
aoqi@1 5182 if (info != NULL) {
aoqi@1 5183 add_call_info_here(info);
aoqi@1 5184 }
aoqi@1 5185 }
aoqi@1 5186
aoqi@1 5187 /* by yyq 7/22/2009
aoqi@1 5188 * i don't know the register allocator will allocate long or double in two consecutive registers
aoqi@1 5189 * if the allocator do like this, the lws below should be removed and lds be used.
aoqi@1 5190 */
aoqi@1 5191
aoqi@1 5192 void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) {
aoqi@1 5193 assert(type == T_LONG, "only for volatile long fields");
aoqi@1 5194 if (info != NULL) {
aoqi@1 5195 add_debug_info_for_null_check_here(info);
aoqi@1 5196 }
aoqi@1 5197
aoqi@1 5198 if(src->is_register() && dest->is_address()) {
aoqi@1 5199 if(src->is_double_cpu()) {
aoqi@1 5200 #ifdef _LP64
aoqi@1 5201 __ sd(src->as_register_lo(), as_Address(dest->as_address_ptr()));
aoqi@1 5202 #else
aoqi@1 5203 __ sw(src->as_register_lo(), as_Address(dest->as_address_ptr()));
aoqi@1 5204 __ sw(src->as_register_hi(), as_Address(dest->as_address_ptr()).base(),
aoqi@1 5205 as_Address(dest->as_address_ptr()).disp() +4);
aoqi@1 5206 #endif
aoqi@1 5207 } else if (src->is_double_fpu()) {
aoqi@1 5208 #ifdef _LP64
aoqi@1 5209 __ sdc1(src->as_fpu_lo(), as_Address(dest->as_address_ptr()));
aoqi@1 5210 #else
aoqi@1 5211 __ swc1(src->as_fpu_lo(), as_Address(dest->as_address_ptr()));
aoqi@1 5212 __ swc1(src->as_fpu_hi(), as_Address(dest->as_address_ptr()).base(),
aoqi@1 5213 as_Address(dest->as_address_ptr()).disp() +4);
aoqi@1 5214 #endif
aoqi@1 5215 } else {
aoqi@1 5216 ShouldNotReachHere();
aoqi@1 5217 }
aoqi@1 5218 } else if (src->is_address() && dest->is_register()){
aoqi@1 5219 if(dest->is_double_cpu()) {
aoqi@1 5220 #ifdef _LP64
aoqi@1 5221 __ ld(dest->as_register_lo(), as_Address(src->as_address_ptr()));
aoqi@1 5222 #else
aoqi@1 5223 __ lw(dest->as_register_lo(), as_Address(src->as_address_ptr()));
aoqi@1 5224 __ lw(dest->as_register_hi(), as_Address(src->as_address_ptr()).base(),
aoqi@1 5225 as_Address(src->as_address_ptr()).disp() +4);
aoqi@1 5226 #endif
aoqi@1 5227 } else if (dest->is_double_fpu()) {
aoqi@1 5228 #ifdef _LP64
aoqi@1 5229 __ ldc1(dest->as_fpu_lo(), as_Address(src->as_address_ptr()));
aoqi@1 5230 #else
aoqi@1 5231 __ lwc1(dest->as_fpu_lo(), as_Address(src->as_address_ptr()));
aoqi@1 5232 __ lwc1(dest->as_fpu_hi(), as_Address(src->as_address_ptr()).base(),
aoqi@1 5233 as_Address(src->as_address_ptr()).disp() +4);
aoqi@1 5234 #endif
aoqi@1 5235 } else {
aoqi@1 5236 ShouldNotReachHere();
aoqi@1 5237 }
aoqi@1 5238 } else {
aoqi@1 5239 ShouldNotReachHere();
aoqi@1 5240 }
aoqi@1 5241 }
aoqi@1 5242
aoqi@1 5243 #ifdef ASSERT
aoqi@1 5244 // emit run-time assertion
aoqi@1 5245 void LIR_Assembler::emit_assert(LIR_OpAssert* op) {
aoqi@1 5246 tty->print_cr("LIR_Assembler::emit_assert unimplemented yet!");
aoqi@1 5247 Unimplemented();
aoqi@1 5248 }
aoqi@1 5249 #endif
aoqi@1 5250
aoqi@1 5251 void LIR_Assembler::membar() {
aoqi@1 5252 __ sync();
aoqi@1 5253 }
aoqi@1 5254
aoqi@1 5255 void LIR_Assembler::membar_acquire() {
aoqi@1 5256 __ sync();
aoqi@1 5257 }
aoqi@1 5258
aoqi@1 5259 void LIR_Assembler::membar_release() {
aoqi@1 5260 __ sync();
aoqi@1 5261 }
aoqi@1 5262
aoqi@1 5263 void LIR_Assembler::membar_loadload() {
aoqi@1 5264 // no-op
aoqi@1 5265 // //__ membar(Assembler::Membar_mask_bits(Assembler::loadload));
aoqi@1 5266 }
aoqi@1 5267
aoqi@1 5268 void LIR_Assembler::membar_storestore() {
aoqi@1 5269 // no-op
aoqi@1 5270 // //__ membar(Assembler::Membar_mask_bits(Assembler::storestore));
aoqi@1 5271 }
aoqi@1 5272
aoqi@1 5273 void LIR_Assembler::membar_loadstore() {
aoqi@1 5274 // no-op
aoqi@1 5275 // //__ membar(Assembler::Membar_mask_bits(Assembler::loadstore));
aoqi@1 5276 }
aoqi@1 5277
aoqi@1 5278 void LIR_Assembler::membar_storeload() {
aoqi@1 5279 //__ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
aoqi@1 5280 }
aoqi@1 5281
aoqi@1 5282
aoqi@1 5283 void LIR_Assembler::get_thread(LIR_Opr result_reg) {
aoqi@1 5284 assert(result_reg->is_register(), "check");
aoqi@1 5285 #ifndef OPT_THREAD
aoqi@1 5286 __ get_thread(NOT_LP64(result_reg->as_register()) LP64_ONLY(result_reg->as_register_lo()));
aoqi@1 5287 #else
aoqi@1 5288 __ move(NOT_LP64(result_reg->as_register()) LP64_ONLY(result_reg->as_register_lo()), TREG);
aoqi@1 5289 #endif
aoqi@1 5290 }
aoqi@1 5291
aoqi@1 5292 void LIR_Assembler::peephole(LIR_List*) {
aoqi@1 5293 // do nothing for now
aoqi@1 5294 }
aoqi@1 5295
aoqi@1 5296 void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp) {
aoqi@1 5297 /* assert(data == dest, "xchg/xadd uses only 2 operands");
aoqi@1 5298
aoqi@1 5299 if (data->type() == T_INT) {
aoqi@1 5300 if (code == lir_xadd) {
aoqi@1 5301 if (os::is_MP()) {
aoqi@1 5302 __ lock();
aoqi@1 5303 }
aoqi@1 5304 __ xaddl(as_Address(src->as_address_ptr()), data->as_register());
aoqi@1 5305 } else {
aoqi@1 5306 __ xchgl(data->as_register(), as_Address(src->as_address_ptr()));
aoqi@1 5307 }
aoqi@1 5308 } else if (data->is_oop()) {
aoqi@1 5309 assert (code == lir_xchg, "xadd for oops");
aoqi@1 5310 Register obj = data->as_register();
aoqi@1 5311 #ifdef _LP64
aoqi@1 5312 if (UseCompressedOops) {
aoqi@1 5313 __ encode_heap_oop(obj);
aoqi@1 5314 __ xchgl(obj, as_Address(src->as_address_ptr()));
aoqi@1 5315 __ decode_heap_oop(obj);
aoqi@1 5316 } else {
aoqi@1 5317 __ xchgptr(obj, as_Address(src->as_address_ptr()));
aoqi@1 5318 }
aoqi@1 5319 #else
aoqi@1 5320 __ xchgl(obj, as_Address(src->as_address_ptr()));
aoqi@1 5321 #endif
aoqi@1 5322 } else if (data->type() == T_LONG) {
aoqi@1 5323 #ifdef _LP64
aoqi@1 5324 assert(data->as_register_lo() == data->as_register_hi(), "should be a single register");
aoqi@1 5325 if (code == lir_xadd) {
aoqi@1 5326 if (os::is_MP()) {
aoqi@1 5327 __ lock();
aoqi@1 5328 }
aoqi@1 5329 __ xaddq(as_Address(src->as_address_ptr()), data->as_register_lo());
aoqi@1 5330 } else {
aoqi@1 5331 __ xchgq(data->as_register_lo(), as_Address(src->as_address_ptr()));
aoqi@1 5332 }
aoqi@1 5333 #else
aoqi@1 5334 ShouldNotReachHere();
aoqi@1 5335 #endif
aoqi@1 5336 } else {
aoqi@1 5337 ShouldNotReachHere();
aoqi@1 5338 }*/
aoqi@1 5339 }
aoqi@1 5340
aoqi@1 5341 #undef __
aoqi@1 5342
aoqi@1 5343
aoqi@1 5344
aoqi@1 5345

mercurial