src/cpu/mips/vm/c1_LIRAssembler_mips.cpp

Thu, 24 May 2018 19:49:50 +0800

author
aoqi
date
Thu, 24 May 2018 19:49:50 +0800
changeset 8865
ffcdff41a92f
parent 6880
52ea28d233d2
child 9126
bc5b8e3dcb6b
permissions
-rw-r--r--

some C1 fix
Contributed-by: chenhaoxuan, zhaixiang, aoqi

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

mercurial