c1_LIRAssembler_x86.cpp revision 2664:c124e2e7463e
1249259Sdim/*
2249259Sdim * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
3249259Sdim * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4249259Sdim *
5249259Sdim * This code is free software; you can redistribute it and/or modify it
6249259Sdim * under the terms of the GNU General Public License version 2 only, as
7249259Sdim * published by the Free Software Foundation.
8249259Sdim *
9249259Sdim * This code is distributed in the hope that it will be useful, but WITHOUT
10249259Sdim * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11249259Sdim * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12249259Sdim * version 2 for more details (a copy is included in the LICENSE file that
13249259Sdim * accompanied this code).
14249259Sdim *
15249259Sdim * You should have received a copy of the GNU General Public License version
16249259Sdim * 2 along with this work; if not, write to the Free Software Foundation,
17249259Sdim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18249259Sdim *
19249259Sdim * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20249259Sdim * or visit www.oracle.com if you need additional information or have any
21249259Sdim * questions.
22249259Sdim *
23249259Sdim */
24249259Sdim
25249259Sdim#include "precompiled.hpp"
26249259Sdim#include "asm/assembler.hpp"
27249259Sdim#include "c1/c1_Compilation.hpp"
28249259Sdim#include "c1/c1_LIRAssembler.hpp"
29249259Sdim#include "c1/c1_MacroAssembler.hpp"
30249259Sdim#include "c1/c1_Runtime1.hpp"
31249259Sdim#include "c1/c1_ValueStack.hpp"
32249259Sdim#include "ci/ciArrayKlass.hpp"
33249259Sdim#include "ci/ciInstance.hpp"
34249259Sdim#include "gc_interface/collectedHeap.hpp"
35249259Sdim#include "memory/barrierSet.hpp"
36249259Sdim#include "memory/cardTableModRefBS.hpp"
37249259Sdim#include "nativeInst_x86.hpp"
38249259Sdim#include "oops/objArrayKlass.hpp"
39249259Sdim#include "runtime/sharedRuntime.hpp"
40249259Sdim
41249259Sdim
42249259Sdim// These masks are used to provide 128-bit aligned bitmasks to the XMM
43249259Sdim// instructions, to allow sign-masking or sign-bit flipping.  They allow
44249259Sdim// fast versions of NegF/NegD and AbsF/AbsD.
45249259Sdim
46249259Sdim// Note: 'double' and 'long long' have 32-bits alignment on x86.
47249259Sdimstatic jlong* double_quadword(jlong *adr, jlong lo, jlong hi) {
48249259Sdim  // Use the expression (adr)&(~0xF) to provide 128-bits aligned address
49249259Sdim  // of 128-bits operands for SSE instructions.
50249259Sdim  jlong *operand = (jlong*)(((intptr_t)adr) & ((intptr_t)(~0xF)));
51249259Sdim  // Store the value to a 128-bits operand.
52249259Sdim  operand[0] = lo;
53249259Sdim  operand[1] = hi;
54249259Sdim  return operand;
55249259Sdim}
56249259Sdim
57249259Sdim// Buffer for 128-bits masks used by SSE instructions.
58249259Sdimstatic jlong fp_signmask_pool[(4+1)*2]; // 4*128bits(data) + 128bits(alignment)
59249259Sdim
60249259Sdim// Static initialization during VM startup.
61249259Sdimstatic jlong *float_signmask_pool  = double_quadword(&fp_signmask_pool[1*2], CONST64(0x7FFFFFFF7FFFFFFF), CONST64(0x7FFFFFFF7FFFFFFF));
62249259Sdimstatic jlong *double_signmask_pool = double_quadword(&fp_signmask_pool[2*2], CONST64(0x7FFFFFFFFFFFFFFF), CONST64(0x7FFFFFFFFFFFFFFF));
63249259Sdimstatic jlong *float_signflip_pool  = double_quadword(&fp_signmask_pool[3*2], CONST64(0x8000000080000000), CONST64(0x8000000080000000));
64249259Sdimstatic jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], CONST64(0x8000000000000000), CONST64(0x8000000000000000));
65249259Sdim
66249259Sdim
67249259Sdim
68249259SdimNEEDS_CLEANUP // remove this definitions ?
69249259Sdimconst Register IC_Klass    = rax;   // where the IC klass is cached
70249259Sdimconst Register SYNC_header = rax;   // synchronization header
71249259Sdimconst Register SHIFT_count = rcx;   // where count for shift operations must be
72249259Sdim
73249259Sdim#define __ _masm->
74249259Sdim
75249259Sdim
76249259Sdimstatic void select_different_registers(Register preserve,
77249259Sdim                                       Register extra,
78249259Sdim                                       Register &tmp1,
79249259Sdim                                       Register &tmp2) {
80249259Sdim  if (tmp1 == preserve) {
81249259Sdim    assert_different_registers(tmp1, tmp2, extra);
82249259Sdim    tmp1 = extra;
83249259Sdim  } else if (tmp2 == preserve) {
84249259Sdim    assert_different_registers(tmp1, tmp2, extra);
85249259Sdim    tmp2 = extra;
86249259Sdim  }
87249259Sdim  assert_different_registers(preserve, tmp1, tmp2);
88249259Sdim}
89249259Sdim
90249259Sdim
91249259Sdim
92249259Sdimstatic void select_different_registers(Register preserve,
93249259Sdim                                       Register extra,
94249259Sdim                                       Register &tmp1,
95249259Sdim                                       Register &tmp2,
96249259Sdim                                       Register &tmp3) {
97249259Sdim  if (tmp1 == preserve) {
98249259Sdim    assert_different_registers(tmp1, tmp2, tmp3, extra);
99249259Sdim    tmp1 = extra;
100249259Sdim  } else if (tmp2 == preserve) {
101249259Sdim    assert_different_registers(tmp1, tmp2, tmp3, extra);
102249259Sdim    tmp2 = extra;
103249259Sdim  } else if (tmp3 == preserve) {
104249259Sdim    assert_different_registers(tmp1, tmp2, tmp3, extra);
105249259Sdim    tmp3 = extra;
106249259Sdim  }
107249259Sdim  assert_different_registers(preserve, tmp1, tmp2, tmp3);
108249259Sdim}
109249259Sdim
110249259Sdim
111249259Sdim
112249259Sdimbool LIR_Assembler::is_small_constant(LIR_Opr opr) {
113249259Sdim  if (opr->is_constant()) {
114249259Sdim    LIR_Const* constant = opr->as_constant_ptr();
115249259Sdim    switch (constant->type()) {
116249259Sdim      case T_INT: {
117249259Sdim        return true;
118249259Sdim      }
119249259Sdim
120249259Sdim      default:
121249259Sdim        return false;
122249259Sdim    }
123249259Sdim  }
124249259Sdim  return false;
125249259Sdim}
126249259Sdim
127249259Sdim
128249259SdimLIR_Opr LIR_Assembler::receiverOpr() {
129249259Sdim  return FrameMap::receiver_opr;
130249259Sdim}
131249259Sdim
132249259SdimLIR_Opr LIR_Assembler::osrBufferPointer() {
133249259Sdim  return FrameMap::as_pointer_opr(receiverOpr()->as_register());
134249259Sdim}
135249259Sdim
136249259Sdim//--------------fpu register translations-----------------------
137249259Sdim
138249259Sdim
139249259Sdimaddress LIR_Assembler::float_constant(float f) {
140249259Sdim  address const_addr = __ float_constant(f);
141249259Sdim  if (const_addr == NULL) {
142249259Sdim    bailout("const section overflow");
143249259Sdim    return __ code()->consts()->start();
144249259Sdim  } else {
145249259Sdim    return const_addr;
146249259Sdim  }
147249259Sdim}
148249259Sdim
149249259Sdim
150249259Sdimaddress LIR_Assembler::double_constant(double d) {
151249259Sdim  address const_addr = __ double_constant(d);
152249259Sdim  if (const_addr == NULL) {
153249259Sdim    bailout("const section overflow");
154249259Sdim    return __ code()->consts()->start();
155249259Sdim  } else {
156249259Sdim    return const_addr;
157249259Sdim  }
158249259Sdim}
159249259Sdim
160249259Sdim
161249259Sdimvoid LIR_Assembler::set_24bit_FPU() {
162249259Sdim  __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24()));
163249259Sdim}
164249259Sdim
165249259Sdimvoid LIR_Assembler::reset_FPU() {
166249259Sdim  __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
167249259Sdim}
168249259Sdim
169249259Sdimvoid LIR_Assembler::fpop() {
170249259Sdim  __ fpop();
171249259Sdim}
172249259Sdim
173249259Sdimvoid LIR_Assembler::fxch(int i) {
174249259Sdim  __ fxch(i);
175249259Sdim}
176249259Sdim
177249259Sdimvoid LIR_Assembler::fld(int i) {
178249259Sdim  __ fld_s(i);
179249259Sdim}
180249259Sdim
181249259Sdimvoid LIR_Assembler::ffree(int i) {
182249259Sdim  __ ffree(i);
183249259Sdim}
184249259Sdim
185249259Sdimvoid LIR_Assembler::breakpoint() {
186249259Sdim  __ int3();
187249259Sdim}
188249259Sdim
189249259Sdimvoid LIR_Assembler::push(LIR_Opr opr) {
190249259Sdim  if (opr->is_single_cpu()) {
191249259Sdim    __ push_reg(opr->as_register());
192249259Sdim  } else if (opr->is_double_cpu()) {
193249259Sdim    NOT_LP64(__ push_reg(opr->as_register_hi()));
194249259Sdim    __ push_reg(opr->as_register_lo());
195249259Sdim  } else if (opr->is_stack()) {
196249259Sdim    __ push_addr(frame_map()->address_for_slot(opr->single_stack_ix()));
197249259Sdim  } else if (opr->is_constant()) {
198249259Sdim    LIR_Const* const_opr = opr->as_constant_ptr();
199249259Sdim    if (const_opr->type() == T_OBJECT) {
200249259Sdim      __ push_oop(const_opr->as_jobject());
201249259Sdim    } else if (const_opr->type() == T_INT) {
202249259Sdim      __ push_jint(const_opr->as_jint());
203249259Sdim    } else {
204249259Sdim      ShouldNotReachHere();
205249259Sdim    }
206249259Sdim
207249259Sdim  } else {
208249259Sdim    ShouldNotReachHere();
209249259Sdim  }
210249259Sdim}
211249259Sdim
212249259Sdimvoid LIR_Assembler::pop(LIR_Opr opr) {
213249259Sdim  if (opr->is_single_cpu()) {
214249259Sdim    __ pop_reg(opr->as_register());
215249259Sdim  } else {
216249259Sdim    ShouldNotReachHere();
217249259Sdim  }
218249259Sdim}
219249259Sdim
220249259Sdimbool LIR_Assembler::is_literal_address(LIR_Address* addr) {
221249259Sdim  return addr->base()->is_illegal() && addr->index()->is_illegal();
222249259Sdim}
223249259Sdim
224249259Sdim//-------------------------------------------
225249259Sdim
226249259SdimAddress LIR_Assembler::as_Address(LIR_Address* addr) {
227249259Sdim  return as_Address(addr, rscratch1);
228249259Sdim}
229249259Sdim
230249259SdimAddress LIR_Assembler::as_Address(LIR_Address* addr, Register tmp) {
231249259Sdim  if (addr->base()->is_illegal()) {
232249259Sdim    assert(addr->index()->is_illegal(), "must be illegal too");
233249259Sdim    AddressLiteral laddr((address)addr->disp(), relocInfo::none);
234249259Sdim    if (! __ reachable(laddr)) {
235249259Sdim      __ movptr(tmp, laddr.addr());
236249259Sdim      Address res(tmp, 0);
237249259Sdim      return res;
238249259Sdim    } else {
239249259Sdim      return __ as_Address(laddr);
240251662Sdim    }
241251662Sdim  }
242251662Sdim
243249259Sdim  Register base = addr->base()->as_pointer_register();
244251662Sdim
245251662Sdim  if (addr->index()->is_illegal()) {
246251662Sdim    return Address( base, addr->disp());
247249259Sdim  } else if (addr->index()->is_cpu_register()) {
248249259Sdim    Register index = addr->index()->as_pointer_register();
249251662Sdim    return Address(base, index, (Address::ScaleFactor) addr->scale(), addr->disp());
250251662Sdim  } else if (addr->index()->is_constant()) {
251251662Sdim    intptr_t addr_offset = (addr->index()->as_constant_ptr()->as_jint() << addr->scale()) + addr->disp();
252251662Sdim    assert(Assembler::is_simm32(addr_offset), "must be");
253251662Sdim
254251662Sdim    return Address(base, addr_offset);
255249259Sdim  } else {
256249259Sdim    Unimplemented();
257249259Sdim    return Address();
258249259Sdim  }
259249259Sdim}
260249259Sdim
261249259Sdim
262249259SdimAddress LIR_Assembler::as_Address_hi(LIR_Address* addr) {
263249259Sdim  Address base = as_Address(addr);
264249259Sdim  return Address(base._base, base._index, base._scale, base._disp + BytesPerWord);
265249259Sdim}
266249259Sdim
267249259Sdim
268249259SdimAddress LIR_Assembler::as_Address_lo(LIR_Address* addr) {
269249259Sdim  return as_Address(addr);
270249259Sdim}
271249259Sdim
272249259Sdim
273251662Sdimvoid LIR_Assembler::osr_entry() {
274251662Sdim  offsets()->set_value(CodeOffsets::OSR_Entry, code_offset());
275251662Sdim  BlockBegin* osr_entry = compilation()->hir()->osr_entry();
276251662Sdim  ValueStack* entry_state = osr_entry->state();
277251662Sdim  int number_of_locks = entry_state->locks_size();
278251662Sdim
279251662Sdim  // we jump here if osr happens with the interpreter
280249259Sdim  // state set up to continue at the beginning of the
281249259Sdim  // loop that triggered osr - in particular, we have
282249259Sdim  // the following registers setup:
283249259Sdim  //
284249259Sdim  // rcx: osr buffer
285249259Sdim  //
286249259Sdim
287249259Sdim  // build frame
288249259Sdim  ciMethod* m = compilation()->method();
289249259Sdim  __ build_frame(initial_frame_size_in_bytes());
290249259Sdim
291249259Sdim  // OSR buffer is
292249259Sdim  //
293249259Sdim  // locals[nlocals-1..0]
294249259Sdim  // monitors[0..number_of_locks]
295249259Sdim  //
296249259Sdim  // locals is a direct copy of the interpreter frame so in the osr buffer
297249259Sdim  // so first slot in the local array is the last local from the interpreter
298249259Sdim  // and last slot is local[0] (receiver) from the interpreter
299249259Sdim  //
300249259Sdim  // Similarly with locks. The first lock slot in the osr buffer is the nth lock
301249259Sdim  // from the interpreter frame, the nth lock slot in the osr buffer is 0th lock
302249259Sdim  // in the interpreter frame (the method lock if a sync method)
303249259Sdim
304249259Sdim  // Initialize monitors in the compiled activation.
305249259Sdim  //   rcx: pointer to osr buffer
306249259Sdim  //
307249259Sdim  // All other registers are dead at this point and the locals will be
308249259Sdim  // copied into place by code emitted in the IR.
309249259Sdim
310249259Sdim  Register OSR_buf = osrBufferPointer()->as_pointer_register();
311249259Sdim  { assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
312249259Sdim    int monitor_offset = BytesPerWord * method()->max_locals() +
313249259Sdim      (2 * BytesPerWord) * (number_of_locks - 1);
314249259Sdim    // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in
315249259Sdim    // the OSR buffer using 2 word entries: first the lock and then
316249259Sdim    // the oop.
317249259Sdim    for (int i = 0; i < number_of_locks; i++) {
318249259Sdim      int slot_offset = monitor_offset - ((i * 2) * BytesPerWord);
319249259Sdim#ifdef ASSERT
320249259Sdim      // verify the interpreter's monitor has a non-null object
321249259Sdim      {
322249259Sdim        Label L;
323249259Sdim        __ cmpptr(Address(OSR_buf, slot_offset + 1*BytesPerWord), (int32_t)NULL_WORD);
324249259Sdim        __ jcc(Assembler::notZero, L);
325249259Sdim        __ stop("locked object is NULL");
326249259Sdim        __ bind(L);
327249259Sdim      }
328249259Sdim#endif
329249259Sdim      __ movptr(rbx, Address(OSR_buf, slot_offset + 0));
330249259Sdim      __ movptr(frame_map()->address_for_monitor_lock(i), rbx);
331249259Sdim      __ movptr(rbx, Address(OSR_buf, slot_offset + 1*BytesPerWord));
332249259Sdim      __ movptr(frame_map()->address_for_monitor_object(i), rbx);
333249259Sdim    }
334249259Sdim  }
335249259Sdim}
336249259Sdim
337249259Sdim
338249259Sdim// inline cache check; done before the frame is built.
339249259Sdimint LIR_Assembler::check_icache() {
340249259Sdim  Register receiver = FrameMap::receiver_opr->as_register();
341249259Sdim  Register ic_klass = IC_Klass;
342249259Sdim  const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
343249259Sdim  const bool do_post_padding = VerifyOops || UseCompressedOops;
344249259Sdim  if (!do_post_padding) {
345249259Sdim    // insert some nops so that the verified entry point is aligned on CodeEntryAlignment
346249259Sdim    while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) {
347249259Sdim      __ nop();
348249259Sdim    }
349249259Sdim  }
350249259Sdim  int offset = __ offset();
351249259Sdim  __ inline_cache_check(receiver, IC_Klass);
352249259Sdim  assert(__ offset() % CodeEntryAlignment == 0 || do_post_padding, "alignment must be correct");
353249259Sdim  if (do_post_padding) {
354249259Sdim    // force alignment after the cache check.
355249259Sdim    // It's been verified to be aligned if !VerifyOops
356249259Sdim    __ align(CodeEntryAlignment);
357249259Sdim  }
358249259Sdim  return offset;
359249259Sdim}
360249259Sdim
361249259Sdim
362249259Sdimvoid LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo* info) {
363249259Sdim  jobject o = NULL;
364249259Sdim  PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_klass_id);
365249259Sdim  __ movoop(reg, o);
366249259Sdim  patching_epilog(patch, lir_patch_normal, reg, info);
367249259Sdim}
368249259Sdim
369249259Sdim
370249259Sdim// This specifies the rsp decrement needed to build the frame
371249259Sdimint LIR_Assembler::initial_frame_size_in_bytes() {
372249259Sdim  // if rounding, must let FrameMap know!
373249259Sdim
374249259Sdim  // The frame_map records size in slots (32bit word)
375249259Sdim
376249259Sdim  // subtract two words to account for return address and link
377249259Sdim  return (frame_map()->framesize() - (2*VMRegImpl::slots_per_word))  * VMRegImpl::stack_slot_size;
378249259Sdim}
379249259Sdim
380249259Sdim
381249259Sdimint LIR_Assembler::emit_exception_handler() {
382249259Sdim  // if the last instruction is a call (typically to do a throw which
383249259Sdim  // is coming at the end after block reordering) the return address
384249259Sdim  // must still point into the code area in order to avoid assertion
385249259Sdim  // failures when searching for the corresponding bci => add a nop
386249259Sdim  // (was bug 5/14/1999 - gri)
387249259Sdim  __ nop();
388249259Sdim
389249259Sdim  // generate code for exception handler
390249259Sdim  address handler_base = __ start_a_stub(exception_handler_size);
391249259Sdim  if (handler_base == NULL) {
392249259Sdim    // not enough space left for the handler
393249259Sdim    bailout("exception handler overflow");
394249259Sdim    return -1;
395249259Sdim  }
396249259Sdim
397249259Sdim  int offset = code_offset();
398249259Sdim
399249259Sdim  // the exception oop and pc are in rax, and rdx
400249259Sdim  // no other registers need to be preserved, so invalidate them
401249259Sdim  __ invalidate_registers(false, true, true, false, true, true);
402249259Sdim
403249259Sdim  // check that there is really an exception
404249259Sdim  __ verify_not_null_oop(rax);
405249259Sdim
406249259Sdim  // search an exception handler (rax: exception oop, rdx: throwing pc)
407249259Sdim  __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_from_callee_id)));
408249259Sdim  __ should_not_reach_here();
409249259Sdim  assert(code_offset() - offset <= exception_handler_size, "overflow");
410249259Sdim  __ end_a_stub();
411249259Sdim
412249259Sdim  return offset;
413249259Sdim}
414249259Sdim
415249259Sdim
416249259Sdim// Emit the code to remove the frame from the stack in the exception
417249259Sdim// unwind path.
418249259Sdimint LIR_Assembler::emit_unwind_handler() {
419249259Sdim#ifndef PRODUCT
420249259Sdim  if (CommentedAssembly) {
421249259Sdim    _masm->block_comment("Unwind handler");
422249259Sdim  }
423249259Sdim#endif
424249259Sdim
425249259Sdim  int offset = code_offset();
426249259Sdim
427249259Sdim  // Fetch the exception from TLS and clear out exception related thread state
428249259Sdim  __ get_thread(rsi);
429249259Sdim  __ movptr(rax, Address(rsi, JavaThread::exception_oop_offset()));
430249259Sdim  __ movptr(Address(rsi, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD);
431249259Sdim  __ movptr(Address(rsi, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD);
432249259Sdim
433249259Sdim  __ bind(_unwind_handler_entry);
434249259Sdim  __ verify_not_null_oop(rax);
435249259Sdim  if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {
436249259Sdim    __ mov(rsi, rax);  // Preserve the exception
437249259Sdim  }
438249259Sdim
439249259Sdim  // Preform needed unlocking
440249259Sdim  MonitorExitStub* stub = NULL;
441249259Sdim  if (method()->is_synchronized()) {
442249259Sdim    monitor_address(0, FrameMap::rax_opr);
443249259Sdim    stub = new MonitorExitStub(FrameMap::rax_opr, true, 0);
444249259Sdim    __ unlock_object(rdi, rbx, rax, *stub->entry());
445249259Sdim    __ bind(*stub->continuation());
446249259Sdim  }
447249259Sdim
448249259Sdim  if (compilation()->env()->dtrace_method_probes()) {
449249259Sdim    __ get_thread(rax);
450249259Sdim    __ movptr(Address(rsp, 0), rax);
451249259Sdim    __ movoop(Address(rsp, sizeof(void*)), method()->constant_encoding());
452249259Sdim    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit)));
453249259Sdim  }
454249259Sdim
455249259Sdim  if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {
456249259Sdim    __ mov(rax, rsi);  // Restore the exception
457249259Sdim  }
458249259Sdim
459249259Sdim  // remove the activation and dispatch to the unwind handler
460249259Sdim  __ remove_frame(initial_frame_size_in_bytes());
461249259Sdim  __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id)));
462249259Sdim
463249259Sdim  // Emit the slow path assembly
464249259Sdim  if (stub != NULL) {
465249259Sdim    stub->emit_code(this);
466249259Sdim  }
467249259Sdim
468249259Sdim  return offset;
469249259Sdim}
470249259Sdim
471249259Sdim
472249259Sdimint LIR_Assembler::emit_deopt_handler() {
473249259Sdim  // if the last instruction is a call (typically to do a throw which
474249259Sdim  // is coming at the end after block reordering) the return address
475249259Sdim  // must still point into the code area in order to avoid assertion
476249259Sdim  // failures when searching for the corresponding bci => add a nop
477249259Sdim  // (was bug 5/14/1999 - gri)
478249259Sdim  __ nop();
479249259Sdim
480249259Sdim  // generate code for exception handler
481249259Sdim  address handler_base = __ start_a_stub(deopt_handler_size);
482249259Sdim  if (handler_base == NULL) {
483249259Sdim    // not enough space left for the handler
484249259Sdim    bailout("deopt handler overflow");
485249259Sdim    return -1;
486263508Sdim  }
487263508Sdim
488249259Sdim  int offset = code_offset();
489249259Sdim  InternalAddress here(__ pc());
490249259Sdim
491249259Sdim  __ pushptr(here.addr());
492249259Sdim  __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
493249259Sdim
494249259Sdim  assert(code_offset() - offset <= deopt_handler_size, "overflow");
495249259Sdim  __ end_a_stub();
496249259Sdim
497249259Sdim  return offset;
498249259Sdim}
499249259Sdim
500249259Sdim
501249259Sdim// This is the fast version of java.lang.String.compare; it has not
502249259Sdim// OSR-entry and therefore, we generate a slow version for OSR's
503249259Sdimvoid LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, CodeEmitInfo* info) {
504249259Sdim  __ movptr (rbx, rcx); // receiver is in rcx
505249259Sdim  __ movptr (rax, arg1->as_register());
506249259Sdim
507249259Sdim  // Get addresses of first characters from both Strings
508249259Sdim  __ load_heap_oop(rsi, Address(rax, java_lang_String::value_offset_in_bytes()));
509249259Sdim  __ movptr       (rcx, Address(rax, java_lang_String::offset_offset_in_bytes()));
510249259Sdim  __ lea          (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
511249259Sdim
512249259Sdim
513249259Sdim  // rbx, may be NULL
514249259Sdim  add_debug_info_for_null_check_here(info);
515249259Sdim  __ load_heap_oop(rdi, Address(rbx, java_lang_String::value_offset_in_bytes()));
516249259Sdim  __ movptr       (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes()));
517249259Sdim  __ lea          (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
518249259Sdim
519249259Sdim  // compute minimum length (in rax) and difference of lengths (on top of stack)
520249259Sdim  __ movl  (rbx, Address(rbx, java_lang_String::count_offset_in_bytes()));
521249259Sdim  __ movl  (rax, Address(rax, java_lang_String::count_offset_in_bytes()));
522249259Sdim  __ mov   (rcx, rbx);
523249259Sdim  __ subptr(rbx, rax); // subtract lengths
524249259Sdim  __ push  (rbx);      // result
525249259Sdim  __ cmov  (Assembler::lessEqual, rax, rcx);
526249259Sdim
527249259Sdim  // is minimum length 0?
528249259Sdim  Label noLoop, haveResult;
529249259Sdim  __ testptr (rax, rax);
530249259Sdim  __ jcc (Assembler::zero, noLoop);
531249259Sdim
532249259Sdim  // compare first characters
533249259Sdim  __ load_unsigned_short(rcx, Address(rdi, 0));
534249259Sdim  __ load_unsigned_short(rbx, Address(rsi, 0));
535249259Sdim  __ subl(rcx, rbx);
536249259Sdim  __ jcc(Assembler::notZero, haveResult);
537249259Sdim  // starting loop
538249259Sdim  __ decrement(rax); // we already tested index: skip one
539249259Sdim  __ jcc(Assembler::zero, noLoop);
540249259Sdim
541249259Sdim  // set rsi.edi to the end of the arrays (arrays have same length)
542249259Sdim  // negate the index
543249259Sdim
544249259Sdim  __ lea(rsi, Address(rsi, rax, Address::times_2, type2aelembytes(T_CHAR)));
545249259Sdim  __ lea(rdi, Address(rdi, rax, Address::times_2, type2aelembytes(T_CHAR)));
546249259Sdim  __ negptr(rax);
547249259Sdim
548249259Sdim  // compare the strings in a loop
549249259Sdim
550249259Sdim  Label loop;
551249259Sdim  __ align(wordSize);
552249259Sdim  __ bind(loop);
553249259Sdim  __ load_unsigned_short(rcx, Address(rdi, rax, Address::times_2, 0));
554249259Sdim  __ load_unsigned_short(rbx, Address(rsi, rax, Address::times_2, 0));
555249259Sdim  __ subl(rcx, rbx);
556249259Sdim  __ jcc(Assembler::notZero, haveResult);
557249259Sdim  __ increment(rax);
558249259Sdim  __ jcc(Assembler::notZero, loop);
559249259Sdim
560249259Sdim  // strings are equal up to min length
561249259Sdim
562249259Sdim  __ bind(noLoop);
563249259Sdim  __ pop(rax);
564249259Sdim  return_op(LIR_OprFact::illegalOpr);
565249259Sdim
566249259Sdim  __ bind(haveResult);
567249259Sdim  // leave instruction is going to discard the TOS value
568249259Sdim  __ mov (rax, rcx); // result of call is in rax,
569249259Sdim}
570249259Sdim
571249259Sdim
572249259Sdimvoid LIR_Assembler::return_op(LIR_Opr result) {
573249259Sdim  assert(result->is_illegal() || !result->is_single_cpu() || result->as_register() == rax, "word returns are in rax,");
574249259Sdim  if (!result->is_illegal() && result->is_float_kind() && !result->is_xmm_register()) {
575249259Sdim    assert(result->fpu() == 0, "result must already be on TOS");
576249259Sdim  }
577249259Sdim
578249259Sdim  // Pop the stack before the safepoint code
579249259Sdim  __ remove_frame(initial_frame_size_in_bytes());
580249259Sdim
581249259Sdim  bool result_is_oop = result->is_valid() ? result->is_oop() : false;
582249259Sdim
583249259Sdim  // Note: we do not need to round double result; float result has the right precision
584249259Sdim  // the poll sets the condition code, but no data registers
585249259Sdim  AddressLiteral polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()),
586249259Sdim                              relocInfo::poll_return_type);
587249259Sdim
588249259Sdim  if (Assembler::is_polling_page_far()) {
589249259Sdim    __ lea(rscratch1, polling_page);
590249259Sdim    __ relocate(relocInfo::poll_return_type);
591249259Sdim    __ testl(rax, Address(rscratch1, 0));
592249259Sdim  } else {
593249259Sdim    __ testl(rax, polling_page);
594249259Sdim  }
595249259Sdim  __ ret(0);
596249259Sdim}
597249259Sdim
598249259Sdim
599249259Sdimint LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
600249259Sdim  AddressLiteral polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()),
601249259Sdim                              relocInfo::poll_type);
602249259Sdim  guarantee(info != NULL, "Shouldn't be NULL");
603249259Sdim  int offset = __ offset();
604249259Sdim  if (Assembler::is_polling_page_far()) {
605249259Sdim    __ lea(rscratch1, polling_page);
606249259Sdim    offset = __ offset();
607249259Sdim    add_debug_info_for_branch(info);
608249259Sdim    __ testl(rax, Address(rscratch1, 0));
609249259Sdim  } else {
610249259Sdim    add_debug_info_for_branch(info);
611249259Sdim    __ testl(rax, polling_page);
612249259Sdim  }
613263508Sdim  return offset;
614249259Sdim}
615249259Sdim
616249259Sdim
617249259Sdimvoid LIR_Assembler::move_regs(Register from_reg, Register to_reg) {
618249259Sdim  if (from_reg != to_reg) __ mov(to_reg, from_reg);
619249259Sdim}
620249259Sdim
621249259Sdimvoid LIR_Assembler::swap_reg(Register a, Register b) {
622249259Sdim  __ xchgptr(a, b);
623249259Sdim}
624249259Sdim
625249259Sdim
626249259Sdimvoid LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
627249259Sdim  assert(src->is_constant(), "should not call otherwise");
628249259Sdim  assert(dest->is_register(), "should not call otherwise");
629249259Sdim  LIR_Const* c = src->as_constant_ptr();
630249259Sdim
631249259Sdim  switch (c->type()) {
632249259Sdim    case T_INT: {
633249259Sdim      assert(patch_code == lir_patch_none, "no patching handled here");
634249259Sdim      __ movl(dest->as_register(), c->as_jint());
635249259Sdim      break;
636249259Sdim    }
637249259Sdim
638249259Sdim    case T_ADDRESS: {
639249259Sdim      assert(patch_code == lir_patch_none, "no patching handled here");
640249259Sdim      __ movptr(dest->as_register(), c->as_jint());
641249259Sdim      break;
642249259Sdim    }
643249259Sdim
644249259Sdim    case T_LONG: {
645249259Sdim      assert(patch_code == lir_patch_none, "no patching handled here");
646249259Sdim#ifdef _LP64
647249259Sdim      __ movptr(dest->as_register_lo(), (intptr_t)c->as_jlong());
648249259Sdim#else
649249259Sdim      __ movptr(dest->as_register_lo(), c->as_jint_lo());
650249259Sdim      __ movptr(dest->as_register_hi(), c->as_jint_hi());
651249259Sdim#endif // _LP64
652249259Sdim      break;
653249259Sdim    }
654249259Sdim
655249259Sdim    case T_OBJECT: {
656249259Sdim      if (patch_code != lir_patch_none) {
657249259Sdim        jobject2reg_with_patching(dest->as_register(), info);
658249259Sdim      } else {
659249259Sdim        __ movoop(dest->as_register(), c->as_jobject());
660249259Sdim      }
661249259Sdim      break;
662249259Sdim    }
663249259Sdim
664249259Sdim    case T_FLOAT: {
665249259Sdim      if (dest->is_single_xmm()) {
666249259Sdim        if (c->is_zero_float()) {
667249259Sdim          __ xorps(dest->as_xmm_float_reg(), dest->as_xmm_float_reg());
668249259Sdim        } else {
669249259Sdim          __ movflt(dest->as_xmm_float_reg(),
670249259Sdim                   InternalAddress(float_constant(c->as_jfloat())));
671249259Sdim        }
672249259Sdim      } else {
673249259Sdim        assert(dest->is_single_fpu(), "must be");
674249259Sdim        assert(dest->fpu_regnr() == 0, "dest must be TOS");
675249259Sdim        if (c->is_zero_float()) {
676249259Sdim          __ fldz();
677249259Sdim        } else if (c->is_one_float()) {
678249259Sdim          __ fld1();
679249259Sdim        } else {
680249259Sdim          __ fld_s (InternalAddress(float_constant(c->as_jfloat())));
681249259Sdim        }
682249259Sdim      }
683249259Sdim      break;
684249259Sdim    }
685249259Sdim
686249259Sdim    case T_DOUBLE: {
687249259Sdim      if (dest->is_double_xmm()) {
688249259Sdim        if (c->is_zero_double()) {
689249259Sdim          __ xorpd(dest->as_xmm_double_reg(), dest->as_xmm_double_reg());
690249259Sdim        } else {
691249259Sdim          __ movdbl(dest->as_xmm_double_reg(),
692249259Sdim                    InternalAddress(double_constant(c->as_jdouble())));
693249259Sdim        }
694249259Sdim      } else {
695249259Sdim        assert(dest->is_double_fpu(), "must be");
696249259Sdim        assert(dest->fpu_regnrLo() == 0, "dest must be TOS");
697249259Sdim        if (c->is_zero_double()) {
698249259Sdim          __ fldz();
699249259Sdim        } else if (c->is_one_double()) {
700249259Sdim          __ fld1();
701249259Sdim        } else {
702249259Sdim          __ fld_d (InternalAddress(double_constant(c->as_jdouble())));
703249259Sdim        }
704249259Sdim      }
705249259Sdim      break;
706249259Sdim    }
707249259Sdim
708249259Sdim    default:
709249259Sdim      ShouldNotReachHere();
710249259Sdim  }
711249259Sdim}
712249259Sdim
713249259Sdimvoid LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) {
714249259Sdim  assert(src->is_constant(), "should not call otherwise");
715249259Sdim  assert(dest->is_stack(), "should not call otherwise");
716249259Sdim  LIR_Const* c = src->as_constant_ptr();
717249259Sdim
718249259Sdim  switch (c->type()) {
719249259Sdim    case T_INT:  // fall through
720249259Sdim    case T_FLOAT:
721249259Sdim      __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits());
722249259Sdim      break;
723249259Sdim
724249259Sdim    case T_ADDRESS:
725249259Sdim      __ movptr(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits());
726249259Sdim      break;
727249259Sdim
728249259Sdim    case T_OBJECT:
729249259Sdim      __ movoop(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jobject());
730249259Sdim      break;
731249259Sdim
732249259Sdim    case T_LONG:  // fall through
733249259Sdim    case T_DOUBLE:
734249259Sdim#ifdef _LP64
735249259Sdim      __ movptr(frame_map()->address_for_slot(dest->double_stack_ix(),
736249259Sdim                                            lo_word_offset_in_bytes), (intptr_t)c->as_jlong_bits());
737249259Sdim#else
738249259Sdim      __ movptr(frame_map()->address_for_slot(dest->double_stack_ix(),
739249259Sdim                                              lo_word_offset_in_bytes), c->as_jint_lo_bits());
740249259Sdim      __ movptr(frame_map()->address_for_slot(dest->double_stack_ix(),
741249259Sdim                                              hi_word_offset_in_bytes), c->as_jint_hi_bits());
742249259Sdim#endif // _LP64
743249259Sdim      break;
744249259Sdim
745249259Sdim    default:
746249259Sdim      ShouldNotReachHere();
747249259Sdim  }
748249259Sdim}
749249259Sdim
750249259Sdimvoid LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) {
751249259Sdim  assert(src->is_constant(), "should not call otherwise");
752249259Sdim  assert(dest->is_address(), "should not call otherwise");
753249259Sdim  LIR_Const* c = src->as_constant_ptr();
754249259Sdim  LIR_Address* addr = dest->as_address_ptr();
755249259Sdim
756249259Sdim  int null_check_here = code_offset();
757249259Sdim  switch (type) {
758249259Sdim    case T_INT:    // fall through
759249259Sdim    case T_FLOAT:
760249259Sdim      __ movl(as_Address(addr), c->as_jint_bits());
761249259Sdim      break;
762249259Sdim
763249259Sdim    case T_ADDRESS:
764249259Sdim      __ movptr(as_Address(addr), c->as_jint_bits());
765249259Sdim      break;
766249259Sdim
767249259Sdim    case T_OBJECT:  // fall through
768249259Sdim    case T_ARRAY:
769249259Sdim      if (c->as_jobject() == NULL) {
770249259Sdim        if (UseCompressedOops && !wide) {
771249259Sdim          __ movl(as_Address(addr), (int32_t)NULL_WORD);
772249259Sdim        } else {
773249259Sdim          __ movptr(as_Address(addr), NULL_WORD);
774249259Sdim        }
775249259Sdim      } else {
776249259Sdim        if (is_literal_address(addr)) {
777249259Sdim          ShouldNotReachHere();
778249259Sdim          __ movoop(as_Address(addr, noreg), c->as_jobject());
779249259Sdim        } else {
780249259Sdim#ifdef _LP64
781249259Sdim          __ movoop(rscratch1, c->as_jobject());
782249259Sdim          if (UseCompressedOops && !wide) {
783249259Sdim            __ encode_heap_oop(rscratch1);
784249259Sdim            null_check_here = code_offset();
785249259Sdim            __ movl(as_Address_lo(addr), rscratch1);
786249259Sdim          } else {
787249259Sdim            null_check_here = code_offset();
788249259Sdim            __ movptr(as_Address_lo(addr), rscratch1);
789249259Sdim          }
790249259Sdim#else
791249259Sdim          __ movoop(as_Address(addr), c->as_jobject());
792249259Sdim#endif
793249259Sdim        }
794249259Sdim      }
795249259Sdim      break;
796249259Sdim
797249259Sdim    case T_LONG:    // fall through
798249259Sdim    case T_DOUBLE:
799249259Sdim#ifdef _LP64
800249259Sdim      if (is_literal_address(addr)) {
801249259Sdim        ShouldNotReachHere();
802249259Sdim        __ movptr(as_Address(addr, r15_thread), (intptr_t)c->as_jlong_bits());
803249259Sdim      } else {
804249259Sdim        __ movptr(r10, (intptr_t)c->as_jlong_bits());
805249259Sdim        null_check_here = code_offset();
806249259Sdim        __ movptr(as_Address_lo(addr), r10);
807249259Sdim      }
808249259Sdim#else
809249259Sdim      // Always reachable in 32bit so this doesn't produce useless move literal
810249259Sdim      __ movptr(as_Address_hi(addr), c->as_jint_hi_bits());
811249259Sdim      __ movptr(as_Address_lo(addr), c->as_jint_lo_bits());
812249259Sdim#endif // _LP64
813249259Sdim      break;
814249259Sdim
815249259Sdim    case T_BOOLEAN: // fall through
816249259Sdim    case T_BYTE:
817249259Sdim      __ movb(as_Address(addr), c->as_jint() & 0xFF);
818249259Sdim      break;
819249259Sdim
820249259Sdim    case T_CHAR:    // fall through
821249259Sdim    case T_SHORT:
822249259Sdim      __ movw(as_Address(addr), c->as_jint() & 0xFFFF);
823249259Sdim      break;
824249259Sdim
825249259Sdim    default:
826249259Sdim      ShouldNotReachHere();
827249259Sdim  };
828249259Sdim
829249259Sdim  if (info != NULL) {
830249259Sdim    add_debug_info_for_null_check(null_check_here, info);
831249259Sdim  }
832249259Sdim}
833249259Sdim
834249259Sdim
835249259Sdimvoid LIR_Assembler::reg2reg(LIR_Opr src, LIR_Opr dest) {
836249259Sdim  assert(src->is_register(), "should not call otherwise");
837249259Sdim  assert(dest->is_register(), "should not call otherwise");
838249259Sdim
839249259Sdim  // move between cpu-registers
840249259Sdim  if (dest->is_single_cpu()) {
841249259Sdim#ifdef _LP64
842249259Sdim    if (src->type() == T_LONG) {
843249259Sdim      // Can do LONG -> OBJECT
844249259Sdim      move_regs(src->as_register_lo(), dest->as_register());
845249259Sdim      return;
846249259Sdim    }
847249259Sdim#endif
848249259Sdim    assert(src->is_single_cpu(), "must match");
849249259Sdim    if (src->type() == T_OBJECT) {
850249259Sdim      __ verify_oop(src->as_register());
851249259Sdim    }
852249259Sdim    move_regs(src->as_register(), dest->as_register());
853249259Sdim
854249259Sdim  } else if (dest->is_double_cpu()) {
855249259Sdim#ifdef _LP64
856249259Sdim    if (src->type() == T_OBJECT || src->type() == T_ARRAY) {
857249259Sdim      // Surprising to me but we can see move of a long to t_object
858249259Sdim      __ verify_oop(src->as_register());
859249259Sdim      move_regs(src->as_register(), dest->as_register_lo());
860249259Sdim      return;
861249259Sdim    }
862249259Sdim#endif
863249259Sdim    assert(src->is_double_cpu(), "must match");
864249259Sdim    Register f_lo = src->as_register_lo();
865249259Sdim    Register f_hi = src->as_register_hi();
866249259Sdim    Register t_lo = dest->as_register_lo();
867249259Sdim    Register t_hi = dest->as_register_hi();
868249259Sdim#ifdef _LP64
869249259Sdim    assert(f_hi == f_lo, "must be same");
870249259Sdim    assert(t_hi == t_lo, "must be same");
871249259Sdim    move_regs(f_lo, t_lo);
872249259Sdim#else
873249259Sdim    assert(f_lo != f_hi && t_lo != t_hi, "invalid register allocation");
874249259Sdim
875249259Sdim
876249259Sdim    if (f_lo == t_hi && f_hi == t_lo) {
877249259Sdim      swap_reg(f_lo, f_hi);
878249259Sdim    } else if (f_hi == t_lo) {
879249259Sdim      assert(f_lo != t_hi, "overwriting register");
880249259Sdim      move_regs(f_hi, t_hi);
881249259Sdim      move_regs(f_lo, t_lo);
882249259Sdim    } else {
883249259Sdim      assert(f_hi != t_lo, "overwriting register");
884249259Sdim      move_regs(f_lo, t_lo);
885249259Sdim      move_regs(f_hi, t_hi);
886249259Sdim    }
887249259Sdim#endif // LP64
888249259Sdim
889249259Sdim    // special moves from fpu-register to xmm-register
890249259Sdim    // necessary for method results
891249259Sdim  } else if (src->is_single_xmm() && !dest->is_single_xmm()) {
892249259Sdim    __ movflt(Address(rsp, 0), src->as_xmm_float_reg());
893249259Sdim    __ fld_s(Address(rsp, 0));
894249259Sdim  } else if (src->is_double_xmm() && !dest->is_double_xmm()) {
895249259Sdim    __ movdbl(Address(rsp, 0), src->as_xmm_double_reg());
896249259Sdim    __ fld_d(Address(rsp, 0));
897249259Sdim  } else if (dest->is_single_xmm() && !src->is_single_xmm()) {
898249259Sdim    __ fstp_s(Address(rsp, 0));
899249259Sdim    __ movflt(dest->as_xmm_float_reg(), Address(rsp, 0));
900249259Sdim  } else if (dest->is_double_xmm() && !src->is_double_xmm()) {
901249259Sdim    __ fstp_d(Address(rsp, 0));
902249259Sdim    __ movdbl(dest->as_xmm_double_reg(), Address(rsp, 0));
903249259Sdim
904249259Sdim    // move between xmm-registers
905249259Sdim  } else if (dest->is_single_xmm()) {
906249259Sdim    assert(src->is_single_xmm(), "must match");
907249259Sdim    __ movflt(dest->as_xmm_float_reg(), src->as_xmm_float_reg());
908249259Sdim  } else if (dest->is_double_xmm()) {
909249259Sdim    assert(src->is_double_xmm(), "must match");
910249259Sdim    __ movdbl(dest->as_xmm_double_reg(), src->as_xmm_double_reg());
911249259Sdim
912249259Sdim    // move between fpu-registers (no instruction necessary because of fpu-stack)
913249259Sdim  } else if (dest->is_single_fpu() || dest->is_double_fpu()) {
914249259Sdim    assert(src->is_single_fpu() || src->is_double_fpu(), "must match");
915249259Sdim    assert(src->fpu() == dest->fpu(), "currently should be nothing to do");
916249259Sdim  } else {
917249259Sdim    ShouldNotReachHere();
918249259Sdim  }
919249259Sdim}
920249259Sdim
921249259Sdimvoid LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool pop_fpu_stack) {
922249259Sdim  assert(src->is_register(), "should not call otherwise");
923249259Sdim  assert(dest->is_stack(), "should not call otherwise");
924249259Sdim
925249259Sdim  if (src->is_single_cpu()) {
926249259Sdim    Address dst = frame_map()->address_for_slot(dest->single_stack_ix());
927249259Sdim    if (type == T_OBJECT || type == T_ARRAY) {
928249259Sdim      __ verify_oop(src->as_register());
929249259Sdim      __ movptr (dst, src->as_register());
930249259Sdim    } else {
931249259Sdim      __ movl (dst, src->as_register());
932249259Sdim    }
933249259Sdim
934249259Sdim  } else if (src->is_double_cpu()) {
935249259Sdim    Address dstLO = frame_map()->address_for_slot(dest->double_stack_ix(), lo_word_offset_in_bytes);
936249259Sdim    Address dstHI = frame_map()->address_for_slot(dest->double_stack_ix(), hi_word_offset_in_bytes);
937249259Sdim    __ movptr (dstLO, src->as_register_lo());
938249259Sdim    NOT_LP64(__ movptr (dstHI, src->as_register_hi()));
939249259Sdim
940249259Sdim  } else if (src->is_single_xmm()) {
941249259Sdim    Address dst_addr = frame_map()->address_for_slot(dest->single_stack_ix());
942249259Sdim    __ movflt(dst_addr, src->as_xmm_float_reg());
943249259Sdim
944249259Sdim  } else if (src->is_double_xmm()) {
945249259Sdim    Address dst_addr = frame_map()->address_for_slot(dest->double_stack_ix());
946249259Sdim    __ movdbl(dst_addr, src->as_xmm_double_reg());
947249259Sdim
948249259Sdim  } else if (src->is_single_fpu()) {
949249259Sdim    assert(src->fpu_regnr() == 0, "argument must be on TOS");
950249259Sdim    Address dst_addr = frame_map()->address_for_slot(dest->single_stack_ix());
951249259Sdim    if (pop_fpu_stack)     __ fstp_s (dst_addr);
952249259Sdim    else                   __ fst_s  (dst_addr);
953249259Sdim
954249259Sdim  } else if (src->is_double_fpu()) {
955249259Sdim    assert(src->fpu_regnrLo() == 0, "argument must be on TOS");
956249259Sdim    Address dst_addr = frame_map()->address_for_slot(dest->double_stack_ix());
957249259Sdim    if (pop_fpu_stack)     __ fstp_d (dst_addr);
958249259Sdim    else                   __ fst_d  (dst_addr);
959249259Sdim
960249259Sdim  } else {
961249259Sdim    ShouldNotReachHere();
962249259Sdim  }
963249259Sdim}
964249259Sdim
965249259Sdim
966249259Sdimvoid LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool wide, bool /* unaligned */) {
967249259Sdim  LIR_Address* to_addr = dest->as_address_ptr();
968249259Sdim  PatchingStub* patch = NULL;
969249259Sdim  Register compressed_src = rscratch1;
970249259Sdim
971249259Sdim  if (type == T_ARRAY || type == T_OBJECT) {
972249259Sdim    __ verify_oop(src->as_register());
973249259Sdim#ifdef _LP64
974249259Sdim    if (UseCompressedOops && !wide) {
975249259Sdim      __ movptr(compressed_src, src->as_register());
976249259Sdim      __ encode_heap_oop(compressed_src);
977249259Sdim    }
978249259Sdim#endif
979249259Sdim  }
980249259Sdim
981249259Sdim  if (patch_code != lir_patch_none) {
982249259Sdim    patch = new PatchingStub(_masm, PatchingStub::access_field_id);
983249259Sdim    Address toa = as_Address(to_addr);
984249259Sdim    assert(toa.disp() != 0, "must have");
985249259Sdim  }
986249259Sdim
987249259Sdim  int null_check_here = code_offset();
988249259Sdim  switch (type) {
989249259Sdim    case T_FLOAT: {
990249259Sdim      if (src->is_single_xmm()) {
991249259Sdim        __ movflt(as_Address(to_addr), src->as_xmm_float_reg());
992249259Sdim      } else {
993249259Sdim        assert(src->is_single_fpu(), "must be");
994249259Sdim        assert(src->fpu_regnr() == 0, "argument must be on TOS");
995249259Sdim        if (pop_fpu_stack)      __ fstp_s(as_Address(to_addr));
996249259Sdim        else                    __ fst_s (as_Address(to_addr));
997249259Sdim      }
998249259Sdim      break;
999249259Sdim    }
1000249259Sdim
1001249259Sdim    case T_DOUBLE: {
1002249259Sdim      if (src->is_double_xmm()) {
1003249259Sdim        __ movdbl(as_Address(to_addr), src->as_xmm_double_reg());
1004249259Sdim      } else {
1005249259Sdim        assert(src->is_double_fpu(), "must be");
1006249259Sdim        assert(src->fpu_regnrLo() == 0, "argument must be on TOS");
1007249259Sdim        if (pop_fpu_stack)      __ fstp_d(as_Address(to_addr));
1008249259Sdim        else                    __ fst_d (as_Address(to_addr));
1009249259Sdim      }
1010249259Sdim      break;
1011249259Sdim    }
1012249259Sdim
1013249259Sdim    case T_ARRAY:   // fall through
1014249259Sdim    case T_OBJECT:  // fall through
1015249259Sdim      if (UseCompressedOops && !wide) {
1016249259Sdim        __ movl(as_Address(to_addr), compressed_src);
1017249259Sdim      } else {
1018249259Sdim        __ movptr(as_Address(to_addr), src->as_register());
1019249259Sdim      }
1020249259Sdim      break;
1021249259Sdim    case T_ADDRESS:
1022249259Sdim      __ movptr(as_Address(to_addr), src->as_register());
1023249259Sdim      break;
1024249259Sdim    case T_INT:
1025249259Sdim      __ movl(as_Address(to_addr), src->as_register());
1026249259Sdim      break;
1027249259Sdim
1028249259Sdim    case T_LONG: {
1029249259Sdim      Register from_lo = src->as_register_lo();
1030249259Sdim      Register from_hi = src->as_register_hi();
1031249259Sdim#ifdef _LP64
1032249259Sdim      __ movptr(as_Address_lo(to_addr), from_lo);
1033249259Sdim#else
1034249259Sdim      Register base = to_addr->base()->as_register();
1035249259Sdim      Register index = noreg;
1036249259Sdim      if (to_addr->index()->is_register()) {
1037249259Sdim        index = to_addr->index()->as_register();
1038249259Sdim      }
1039249259Sdim      if (base == from_lo || index == from_lo) {
1040249259Sdim        assert(base != from_hi, "can't be");
1041249259Sdim        assert(index == noreg || (index != base && index != from_hi), "can't handle this");
1042249259Sdim        __ movl(as_Address_hi(to_addr), from_hi);
1043249259Sdim        if (patch != NULL) {
1044249259Sdim          patching_epilog(patch, lir_patch_high, base, info);
1045249259Sdim          patch = new PatchingStub(_masm, PatchingStub::access_field_id);
1046249259Sdim          patch_code = lir_patch_low;
1047249259Sdim        }
1048249259Sdim        __ movl(as_Address_lo(to_addr), from_lo);
1049249259Sdim      } else {
1050249259Sdim        assert(index == noreg || (index != base && index != from_lo), "can't handle this");
1051249259Sdim        __ movl(as_Address_lo(to_addr), from_lo);
1052249259Sdim        if (patch != NULL) {
1053249259Sdim          patching_epilog(patch, lir_patch_low, base, info);
1054249259Sdim          patch = new PatchingStub(_masm, PatchingStub::access_field_id);
1055249259Sdim          patch_code = lir_patch_high;
1056249259Sdim        }
1057249259Sdim        __ movl(as_Address_hi(to_addr), from_hi);
1058249259Sdim      }
1059249259Sdim#endif // _LP64
1060249259Sdim      break;
1061249259Sdim    }
1062249259Sdim
1063249259Sdim    case T_BYTE:    // fall through
1064249259Sdim    case T_BOOLEAN: {
1065249259Sdim      Register src_reg = src->as_register();
1066249259Sdim      Address dst_addr = as_Address(to_addr);
1067249259Sdim      assert(VM_Version::is_P6() || src_reg->has_byte_register(), "must use byte registers if not P6");
1068249259Sdim      __ movb(dst_addr, src_reg);
1069249259Sdim      break;
1070249259Sdim    }
1071249259Sdim
1072249259Sdim    case T_CHAR:    // fall through
1073249259Sdim    case T_SHORT:
1074249259Sdim      __ movw(as_Address(to_addr), src->as_register());
1075249259Sdim      break;
1076249259Sdim
1077249259Sdim    default:
1078249259Sdim      ShouldNotReachHere();
1079249259Sdim  }
1080249259Sdim  if (info != NULL) {
1081249259Sdim    add_debug_info_for_null_check(null_check_here, info);
1082249259Sdim  }
1083249259Sdim
1084249259Sdim  if (patch_code != lir_patch_none) {
1085249259Sdim    patching_epilog(patch, patch_code, to_addr->base()->as_register(), info);
1086249259Sdim  }
1087249259Sdim}
1088249259Sdim
1089249259Sdim
1090249259Sdimvoid LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) {
1091249259Sdim  assert(src->is_stack(), "should not call otherwise");
1092249259Sdim  assert(dest->is_register(), "should not call otherwise");
1093249259Sdim
1094249259Sdim  if (dest->is_single_cpu()) {
1095249259Sdim    if (type == T_ARRAY || type == T_OBJECT) {
1096249259Sdim      __ movptr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()));
1097249259Sdim      __ verify_oop(dest->as_register());
1098249259Sdim    } else {
1099249259Sdim      __ movl(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()));
1100249259Sdim    }
1101249259Sdim
1102249259Sdim  } else if (dest->is_double_cpu()) {
1103249259Sdim    Address src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix(), lo_word_offset_in_bytes);
1104249259Sdim    Address src_addr_HI = frame_map()->address_for_slot(src->double_stack_ix(), hi_word_offset_in_bytes);
1105249259Sdim    __ movptr(dest->as_register_lo(), src_addr_LO);
1106249259Sdim    NOT_LP64(__ movptr(dest->as_register_hi(), src_addr_HI));
1107249259Sdim
1108249259Sdim  } else if (dest->is_single_xmm()) {
1109249259Sdim    Address src_addr = frame_map()->address_for_slot(src->single_stack_ix());
1110249259Sdim    __ movflt(dest->as_xmm_float_reg(), src_addr);
1111249259Sdim
1112249259Sdim  } else if (dest->is_double_xmm()) {
1113249259Sdim    Address src_addr = frame_map()->address_for_slot(src->double_stack_ix());
1114249259Sdim    __ movdbl(dest->as_xmm_double_reg(), src_addr);
1115249259Sdim
1116249259Sdim  } else if (dest->is_single_fpu()) {
1117249259Sdim    assert(dest->fpu_regnr() == 0, "dest must be TOS");
1118249259Sdim    Address src_addr = frame_map()->address_for_slot(src->single_stack_ix());
1119249259Sdim    __ fld_s(src_addr);
1120249259Sdim
1121249259Sdim  } else if (dest->is_double_fpu()) {
1122249259Sdim    assert(dest->fpu_regnrLo() == 0, "dest must be TOS");
1123249259Sdim    Address src_addr = frame_map()->address_for_slot(src->double_stack_ix());
1124249259Sdim    __ fld_d(src_addr);
1125249259Sdim
1126249259Sdim  } else {
1127249259Sdim    ShouldNotReachHere();
1128249259Sdim  }
1129263508Sdim}
1130249259Sdim
1131249259Sdim
1132249259Sdimvoid LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) {
1133249259Sdim  if (src->is_single_stack()) {
1134249259Sdim    if (type == T_OBJECT || type == T_ARRAY) {
1135249259Sdim      __ pushptr(frame_map()->address_for_slot(src ->single_stack_ix()));
1136249259Sdim      __ popptr (frame_map()->address_for_slot(dest->single_stack_ix()));
1137249259Sdim    } else {
1138249259Sdim#ifndef _LP64
1139249259Sdim      __ pushl(frame_map()->address_for_slot(src ->single_stack_ix()));
1140249259Sdim      __ popl (frame_map()->address_for_slot(dest->single_stack_ix()));
1141249259Sdim#else
1142249259Sdim      //no pushl on 64bits
1143249259Sdim      __ movl(rscratch1, frame_map()->address_for_slot(src ->single_stack_ix()));
1144249259Sdim      __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), rscratch1);
1145249259Sdim#endif
1146249259Sdim    }
1147249259Sdim
1148249259Sdim  } else if (src->is_double_stack()) {
1149249259Sdim#ifdef _LP64
1150249259Sdim    __ pushptr(frame_map()->address_for_slot(src ->double_stack_ix()));
1151249259Sdim    __ popptr (frame_map()->address_for_slot(dest->double_stack_ix()));
1152249259Sdim#else
1153249259Sdim    __ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), 0));
1154249259Sdim    // push and pop the part at src + wordSize, adding wordSize for the previous push
1155249259Sdim    __ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), 2 * wordSize));
1156249259Sdim    __ popl (frame_map()->address_for_slot(dest->double_stack_ix(), 2 * wordSize));
1157249259Sdim    __ popl (frame_map()->address_for_slot(dest->double_stack_ix(), 0));
1158249259Sdim#endif // _LP64
1159249259Sdim
1160249259Sdim  } else {
1161249259Sdim    ShouldNotReachHere();
1162249259Sdim  }
1163249259Sdim}
1164249259Sdim
1165249259Sdim
1166249259Sdimvoid LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool /* unaligned */) {
1167249259Sdim  assert(src->is_address(), "should not call otherwise");
1168249259Sdim  assert(dest->is_register(), "should not call otherwise");
1169249259Sdim
1170249259Sdim  LIR_Address* addr = src->as_address_ptr();
1171249259Sdim  Address from_addr = as_Address(addr);
1172249259Sdim
1173249259Sdim  switch (type) {
1174249259Sdim    case T_BOOLEAN: // fall through
1175249259Sdim    case T_BYTE:    // fall through
1176249259Sdim    case T_CHAR:    // fall through
1177249259Sdim    case T_SHORT:
1178249259Sdim      if (!VM_Version::is_P6() && !from_addr.uses(dest->as_register())) {
1179249259Sdim        // on pre P6 processors we may get partial register stalls
1180249259Sdim        // so blow away the value of to_rinfo before loading a
1181249259Sdim        // partial word into it.  Do it here so that it precedes
1182249259Sdim        // the potential patch point below.
1183249259Sdim        __ xorptr(dest->as_register(), dest->as_register());
1184249259Sdim      }
1185249259Sdim      break;
1186249259Sdim  }
1187249259Sdim
1188249259Sdim  PatchingStub* patch = NULL;
1189249259Sdim  if (patch_code != lir_patch_none) {
1190249259Sdim    patch = new PatchingStub(_masm, PatchingStub::access_field_id);
1191249259Sdim    assert(from_addr.disp() != 0, "must have");
1192249259Sdim  }
1193249259Sdim  if (info != NULL) {
1194249259Sdim    add_debug_info_for_null_check_here(info);
1195249259Sdim  }
1196249259Sdim
1197249259Sdim  switch (type) {
1198249259Sdim    case T_FLOAT: {
1199249259Sdim      if (dest->is_single_xmm()) {
1200249259Sdim        __ movflt(dest->as_xmm_float_reg(), from_addr);
1201249259Sdim      } else {
1202249259Sdim        assert(dest->is_single_fpu(), "must be");
1203249259Sdim        assert(dest->fpu_regnr() == 0, "dest must be TOS");
1204249259Sdim        __ fld_s(from_addr);
1205249259Sdim      }
1206249259Sdim      break;
1207249259Sdim    }
1208249259Sdim
1209249259Sdim    case T_DOUBLE: {
1210249259Sdim      if (dest->is_double_xmm()) {
1211249259Sdim        __ movdbl(dest->as_xmm_double_reg(), from_addr);
1212249259Sdim      } else {
1213249259Sdim        assert(dest->is_double_fpu(), "must be");
1214249259Sdim        assert(dest->fpu_regnrLo() == 0, "dest must be TOS");
1215249259Sdim        __ fld_d(from_addr);
1216249259Sdim      }
1217249259Sdim      break;
1218249259Sdim    }
1219249259Sdim
1220249259Sdim    case T_OBJECT:  // fall through
1221249259Sdim    case T_ARRAY:   // fall through
1222249259Sdim      if (UseCompressedOops && !wide) {
1223249259Sdim        __ movl(dest->as_register(), from_addr);
1224249259Sdim      } else {
1225249259Sdim        __ movptr(dest->as_register(), from_addr);
1226249259Sdim      }
1227249259Sdim      break;
1228249259Sdim
1229249259Sdim    case T_ADDRESS:
1230249259Sdim      __ movptr(dest->as_register(), from_addr);
1231249259Sdim      break;
1232249259Sdim    case T_INT:
1233249259Sdim      __ movl(dest->as_register(), from_addr);
1234249259Sdim      break;
1235249259Sdim
1236249259Sdim    case T_LONG: {
1237249259Sdim      Register to_lo = dest->as_register_lo();
1238249259Sdim      Register to_hi = dest->as_register_hi();
1239249259Sdim#ifdef _LP64
1240249259Sdim      __ movptr(to_lo, as_Address_lo(addr));
1241249259Sdim#else
1242249259Sdim      Register base = addr->base()->as_register();
1243249259Sdim      Register index = noreg;
1244249259Sdim      if (addr->index()->is_register()) {
1245249259Sdim        index = addr->index()->as_register();
1246249259Sdim      }
1247249259Sdim      if ((base == to_lo && index == to_hi) ||
1248249259Sdim          (base == to_hi && index == to_lo)) {
1249249259Sdim        // addresses with 2 registers are only formed as a result of
1250249259Sdim        // array access so this code will never have to deal with
1251249259Sdim        // patches or null checks.
1252249259Sdim        assert(info == NULL && patch == NULL, "must be");
1253249259Sdim        __ lea(to_hi, as_Address(addr));
1254249259Sdim        __ movl(to_lo, Address(to_hi, 0));
1255249259Sdim        __ movl(to_hi, Address(to_hi, BytesPerWord));
1256249259Sdim      } else if (base == to_lo || index == to_lo) {
1257249259Sdim        assert(base != to_hi, "can't be");
1258249259Sdim        assert(index == noreg || (index != base && index != to_hi), "can't handle this");
1259249259Sdim        __ movl(to_hi, as_Address_hi(addr));
1260249259Sdim        if (patch != NULL) {
1261249259Sdim          patching_epilog(patch, lir_patch_high, base, info);
1262249259Sdim          patch = new PatchingStub(_masm, PatchingStub::access_field_id);
1263249259Sdim          patch_code = lir_patch_low;
1264249259Sdim        }
1265249259Sdim        __ movl(to_lo, as_Address_lo(addr));
1266249259Sdim      } else {
1267249259Sdim        assert(index == noreg || (index != base && index != to_lo), "can't handle this");
1268249259Sdim        __ movl(to_lo, as_Address_lo(addr));
1269249259Sdim        if (patch != NULL) {
1270249259Sdim          patching_epilog(patch, lir_patch_low, base, info);
1271249259Sdim          patch = new PatchingStub(_masm, PatchingStub::access_field_id);
1272249259Sdim          patch_code = lir_patch_high;
1273249259Sdim        }
1274249259Sdim        __ movl(to_hi, as_Address_hi(addr));
1275249259Sdim      }
1276249259Sdim#endif // _LP64
1277249259Sdim      break;
1278249259Sdim    }
1279249259Sdim
1280249259Sdim    case T_BOOLEAN: // fall through
1281249259Sdim    case T_BYTE: {
1282249259Sdim      Register dest_reg = dest->as_register();
1283249259Sdim      assert(VM_Version::is_P6() || dest_reg->has_byte_register(), "must use byte registers if not P6");
1284249259Sdim      if (VM_Version::is_P6() || from_addr.uses(dest_reg)) {
1285249259Sdim        __ movsbl(dest_reg, from_addr);
1286249259Sdim      } else {
1287249259Sdim        __ movb(dest_reg, from_addr);
1288249259Sdim        __ shll(dest_reg, 24);
1289249259Sdim        __ sarl(dest_reg, 24);
1290249259Sdim      }
1291249259Sdim      break;
1292249259Sdim    }
1293249259Sdim
1294249259Sdim    case T_CHAR: {
1295249259Sdim      Register dest_reg = dest->as_register();
1296249259Sdim      assert(VM_Version::is_P6() || dest_reg->has_byte_register(), "must use byte registers if not P6");
1297249259Sdim      if (VM_Version::is_P6() || from_addr.uses(dest_reg)) {
1298249259Sdim        __ movzwl(dest_reg, from_addr);
1299249259Sdim      } else {
1300249259Sdim        __ movw(dest_reg, from_addr);
1301249259Sdim      }
1302249259Sdim      break;
1303249259Sdim    }
1304249259Sdim
1305249259Sdim    case T_SHORT: {
1306249259Sdim      Register dest_reg = dest->as_register();
1307249259Sdim      if (VM_Version::is_P6() || from_addr.uses(dest_reg)) {
1308249259Sdim        __ movswl(dest_reg, from_addr);
1309249259Sdim      } else {
1310249259Sdim        __ movw(dest_reg, from_addr);
1311249259Sdim        __ shll(dest_reg, 16);
1312249259Sdim        __ sarl(dest_reg, 16);
1313249259Sdim      }
1314249259Sdim      break;
1315249259Sdim    }
1316249259Sdim
1317249259Sdim    default:
1318249259Sdim      ShouldNotReachHere();
1319249259Sdim  }
1320249259Sdim
1321249259Sdim  if (patch != NULL) {
1322249259Sdim    patching_epilog(patch, patch_code, addr->base()->as_register(), info);
1323249259Sdim  }
1324249259Sdim
1325249259Sdim  if (type == T_ARRAY || type == T_OBJECT) {
1326249259Sdim#ifdef _LP64
1327249259Sdim    if (UseCompressedOops && !wide) {
1328249259Sdim      __ decode_heap_oop(dest->as_register());
1329249259Sdim    }
1330249259Sdim#endif
1331249259Sdim    __ verify_oop(dest->as_register());
1332249259Sdim  }
1333249259Sdim}
1334249259Sdim
1335249259Sdim
1336249259Sdimvoid LIR_Assembler::prefetchr(LIR_Opr src) {
1337249259Sdim  LIR_Address* addr = src->as_address_ptr();
1338249259Sdim  Address from_addr = as_Address(addr);
1339249259Sdim
1340249259Sdim  if (VM_Version::supports_sse()) {
1341249259Sdim    switch (ReadPrefetchInstr) {
1342249259Sdim      case 0:
1343249259Sdim        __ prefetchnta(from_addr); break;
1344249259Sdim      case 1:
1345249259Sdim        __ prefetcht0(from_addr); break;
1346249259Sdim      case 2:
1347249259Sdim        __ prefetcht2(from_addr); break;
1348249259Sdim      default:
1349249259Sdim        ShouldNotReachHere(); break;
1350249259Sdim    }
1351249259Sdim  } else if (VM_Version::supports_3dnow_prefetch()) {
1352249259Sdim    __ prefetchr(from_addr);
1353249259Sdim  }
1354249259Sdim}
1355249259Sdim
1356249259Sdim
1357249259Sdimvoid LIR_Assembler::prefetchw(LIR_Opr src) {
1358249259Sdim  LIR_Address* addr = src->as_address_ptr();
1359249259Sdim  Address from_addr = as_Address(addr);
1360249259Sdim
1361249259Sdim  if (VM_Version::supports_sse()) {
1362249259Sdim    switch (AllocatePrefetchInstr) {
1363249259Sdim      case 0:
1364249259Sdim        __ prefetchnta(from_addr); break;
1365249259Sdim      case 1:
1366249259Sdim        __ prefetcht0(from_addr); break;
1367249259Sdim      case 2:
1368249259Sdim        __ prefetcht2(from_addr); break;
1369249259Sdim      case 3:
1370249259Sdim        __ prefetchw(from_addr); break;
1371249259Sdim      default:
1372249259Sdim        ShouldNotReachHere(); break;
1373249259Sdim    }
1374249259Sdim  } else if (VM_Version::supports_3dnow_prefetch()) {
1375249259Sdim    __ prefetchw(from_addr);
1376249259Sdim  }
1377249259Sdim}
1378249259Sdim
1379249259Sdim
1380249259SdimNEEDS_CLEANUP; // This could be static?
1381249259SdimAddress::ScaleFactor LIR_Assembler::array_element_size(BasicType type) const {
1382249259Sdim  int elem_size = type2aelembytes(type);
1383249259Sdim  switch (elem_size) {
1384249259Sdim    case 1: return Address::times_1;
1385249259Sdim    case 2: return Address::times_2;
1386249259Sdim    case 4: return Address::times_4;
1387249259Sdim    case 8: return Address::times_8;
1388249259Sdim  }
1389249259Sdim  ShouldNotReachHere();
1390249259Sdim  return Address::no_scale;
1391249259Sdim}
1392249259Sdim
1393263508Sdim
1394249259Sdimvoid LIR_Assembler::emit_op3(LIR_Op3* op) {
1395249259Sdim  switch (op->code()) {
1396249259Sdim    case lir_idiv:
1397249259Sdim    case lir_irem:
1398249259Sdim      arithmetic_idiv(op->code(),
1399249259Sdim                      op->in_opr1(),
1400249259Sdim                      op->in_opr2(),
1401249259Sdim                      op->in_opr3(),
1402249259Sdim                      op->result_opr(),
1403249259Sdim                      op->info());
1404249259Sdim      break;
1405249259Sdim    default:      ShouldNotReachHere(); break;
1406249259Sdim  }
1407249259Sdim}
1408249259Sdim
1409249259Sdimvoid LIR_Assembler::emit_opBranch(LIR_OpBranch* op) {
1410249259Sdim#ifdef ASSERT
1411249259Sdim  assert(op->block() == NULL || op->block()->label() == op->label(), "wrong label");
1412249259Sdim  if (op->block() != NULL)  _branch_target_blocks.append(op->block());
1413249259Sdim  if (op->ublock() != NULL) _branch_target_blocks.append(op->ublock());
1414249259Sdim#endif
1415249259Sdim
1416249259Sdim  if (op->cond() == lir_cond_always) {
1417249259Sdim    if (op->info() != NULL) add_debug_info_for_branch(op->info());
1418249259Sdim    __ jmp (*(op->label()));
1419249259Sdim  } else {
1420249259Sdim    Assembler::Condition acond = Assembler::zero;
1421249259Sdim    if (op->code() == lir_cond_float_branch) {
1422249259Sdim      assert(op->ublock() != NULL, "must have unordered successor");
1423249259Sdim      __ jcc(Assembler::parity, *(op->ublock()->label()));
1424249259Sdim      switch(op->cond()) {
1425249259Sdim        case lir_cond_equal:        acond = Assembler::equal;      break;
1426249259Sdim        case lir_cond_notEqual:     acond = Assembler::notEqual;   break;
1427249259Sdim        case lir_cond_less:         acond = Assembler::below;      break;
1428249259Sdim        case lir_cond_lessEqual:    acond = Assembler::belowEqual; break;
1429249259Sdim        case lir_cond_greaterEqual: acond = Assembler::aboveEqual; break;
1430249259Sdim        case lir_cond_greater:      acond = Assembler::above;      break;
1431249259Sdim        default:                         ShouldNotReachHere();
1432249259Sdim      }
1433249259Sdim    } else {
1434249259Sdim      switch (op->cond()) {
1435249259Sdim        case lir_cond_equal:        acond = Assembler::equal;       break;
1436249259Sdim        case lir_cond_notEqual:     acond = Assembler::notEqual;    break;
1437249259Sdim        case lir_cond_less:         acond = Assembler::less;        break;
1438249259Sdim        case lir_cond_lessEqual:    acond = Assembler::lessEqual;   break;
1439249259Sdim        case lir_cond_greaterEqual: acond = Assembler::greaterEqual;break;
1440249259Sdim        case lir_cond_greater:      acond = Assembler::greater;     break;
1441249259Sdim        case lir_cond_belowEqual:   acond = Assembler::belowEqual;  break;
1442249259Sdim        case lir_cond_aboveEqual:   acond = Assembler::aboveEqual;  break;
1443249259Sdim        default:                         ShouldNotReachHere();
1444249259Sdim      }
1445249259Sdim    }
1446249259Sdim    __ jcc(acond,*(op->label()));
1447249259Sdim  }
1448249259Sdim}
1449249259Sdim
1450249259Sdimvoid LIR_Assembler::emit_opConvert(LIR_OpConvert* op) {
1451249259Sdim  LIR_Opr src  = op->in_opr();
1452249259Sdim  LIR_Opr dest = op->result_opr();
1453249259Sdim
1454249259Sdim  switch (op->bytecode()) {
1455249259Sdim    case Bytecodes::_i2l:
1456249259Sdim#ifdef _LP64
1457249259Sdim      __ movl2ptr(dest->as_register_lo(), src->as_register());
1458249259Sdim#else
1459249259Sdim      move_regs(src->as_register(), dest->as_register_lo());
1460249259Sdim      move_regs(src->as_register(), dest->as_register_hi());
1461249259Sdim      __ sarl(dest->as_register_hi(), 31);
1462249259Sdim#endif // LP64
1463249259Sdim      break;
1464249259Sdim
1465263508Sdim    case Bytecodes::_l2i:
1466249259Sdim      move_regs(src->as_register_lo(), dest->as_register());
1467249259Sdim      break;
1468249259Sdim
1469249259Sdim    case Bytecodes::_i2b:
1470249259Sdim      move_regs(src->as_register(), dest->as_register());
1471249259Sdim      __ sign_extend_byte(dest->as_register());
1472249259Sdim      break;
1473249259Sdim
1474249259Sdim    case Bytecodes::_i2c:
1475249259Sdim      move_regs(src->as_register(), dest->as_register());
1476249259Sdim      __ andl(dest->as_register(), 0xFFFF);
1477249259Sdim      break;
1478249259Sdim
1479249259Sdim    case Bytecodes::_i2s:
1480249259Sdim      move_regs(src->as_register(), dest->as_register());
1481249259Sdim      __ sign_extend_short(dest->as_register());
1482249259Sdim      break;
1483249259Sdim
1484249259Sdim
1485249259Sdim    case Bytecodes::_f2d:
1486249259Sdim    case Bytecodes::_d2f:
1487249259Sdim      if (dest->is_single_xmm()) {
1488249259Sdim        __ cvtsd2ss(dest->as_xmm_float_reg(), src->as_xmm_double_reg());
1489249259Sdim      } else if (dest->is_double_xmm()) {
1490249259Sdim        __ cvtss2sd(dest->as_xmm_double_reg(), src->as_xmm_float_reg());
1491249259Sdim      } else {
1492249259Sdim        assert(src->fpu() == dest->fpu(), "register must be equal");
1493249259Sdim        // do nothing (float result is rounded later through spilling)
1494263508Sdim      }
1495263508Sdim      break;
1496263508Sdim
1497263508Sdim    case Bytecodes::_i2f:
1498263508Sdim    case Bytecodes::_i2d:
1499249259Sdim      if (dest->is_single_xmm()) {
1500249259Sdim        __ cvtsi2ssl(dest->as_xmm_float_reg(), src->as_register());
1501249259Sdim      } else if (dest->is_double_xmm()) {
1502263508Sdim        __ cvtsi2sdl(dest->as_xmm_double_reg(), src->as_register());
1503263508Sdim      } else {
1504263508Sdim        assert(dest->fpu() == 0, "result must be on TOS");
1505263508Sdim        __ movl(Address(rsp, 0), src->as_register());
1506263508Sdim        __ fild_s(Address(rsp, 0));
1507263508Sdim      }
1508263508Sdim      break;
1509263508Sdim
1510263508Sdim    case Bytecodes::_f2i:
1511263508Sdim    case Bytecodes::_d2i:
1512263508Sdim      if (src->is_single_xmm()) {
1513263508Sdim        __ cvttss2sil(dest->as_register(), src->as_xmm_float_reg());
1514249259Sdim      } else if (src->is_double_xmm()) {
1515249259Sdim        __ cvttsd2sil(dest->as_register(), src->as_xmm_double_reg());
1516249259Sdim      } else {
1517249259Sdim        assert(src->fpu() == 0, "input must be on TOS");
1518249259Sdim        __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_trunc()));
1519249259Sdim        __ fist_s(Address(rsp, 0));
1520249259Sdim        __ movl(dest->as_register(), Address(rsp, 0));
1521249259Sdim        __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
1522249259Sdim      }
1523249259Sdim
1524249259Sdim      // IA32 conversion instructions do not match JLS for overflow, underflow and NaN -> fixup in stub
1525249259Sdim      assert(op->stub() != NULL, "stub required");
1526249259Sdim      __ cmpl(dest->as_register(), 0x80000000);
1527249259Sdim      __ jcc(Assembler::equal, *op->stub()->entry());
1528249259Sdim      __ bind(*op->stub()->continuation());
1529249259Sdim      break;
1530249259Sdim
1531249259Sdim    case Bytecodes::_l2f:
1532249259Sdim    case Bytecodes::_l2d:
1533249259Sdim      assert(!dest->is_xmm_register(), "result in xmm register not supported (no SSE instruction present)");
1534249259Sdim      assert(dest->fpu() == 0, "result must be on TOS");
1535249259Sdim
1536249259Sdim      __ movptr(Address(rsp, 0),            src->as_register_lo());
1537249259Sdim      NOT_LP64(__ movl(Address(rsp, BytesPerWord), src->as_register_hi()));
1538249259Sdim      __ fild_d(Address(rsp, 0));
1539249259Sdim      // float result is rounded later through spilling
1540249259Sdim      break;
1541249259Sdim
1542249259Sdim    case Bytecodes::_f2l:
1543249259Sdim    case Bytecodes::_d2l:
1544249259Sdim      assert(!src->is_xmm_register(), "input in xmm register not supported (no SSE instruction present)");
1545249259Sdim      assert(src->fpu() == 0, "input must be on TOS");
1546249259Sdim      assert(dest == FrameMap::long0_opr, "runtime stub places result in these registers");
1547249259Sdim
1548249259Sdim      // instruction sequence too long to inline it here
1549249259Sdim      {
1550249259Sdim        __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::fpu2long_stub_id)));
1551249259Sdim      }
1552249259Sdim      break;
1553249259Sdim
1554249259Sdim    default: ShouldNotReachHere();
1555249259Sdim  }
1556249259Sdim}
1557249259Sdim
1558249259Sdimvoid LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) {
1559249259Sdim  if (op->init_check()) {
1560249259Sdim    __ cmpl(Address(op->klass()->as_register(),
1561249259Sdim                    instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)),
1562249259Sdim            instanceKlass::fully_initialized);
1563249259Sdim    add_debug_info_for_null_check_here(op->stub()->info());
1564249259Sdim    __ jcc(Assembler::notEqual, *op->stub()->entry());
1565249259Sdim  }
1566249259Sdim  __ allocate_object(op->obj()->as_register(),
1567249259Sdim                     op->tmp1()->as_register(),
1568249259Sdim                     op->tmp2()->as_register(),
1569249259Sdim                     op->header_size(),
1570249259Sdim                     op->object_size(),
1571249259Sdim                     op->klass()->as_register(),
1572249259Sdim                     *op->stub()->entry());
1573249259Sdim  __ bind(*op->stub()->continuation());
1574249259Sdim}
1575249259Sdim
1576249259Sdimvoid LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) {
1577249259Sdim  Register len =  op->len()->as_register();
1578249259Sdim  LP64_ONLY( __ movslq(len, len); )
1579249259Sdim
1580249259Sdim  if (UseSlowPath ||
1581249259Sdim      (!UseFastNewObjectArray && (op->type() == T_OBJECT || op->type() == T_ARRAY)) ||
1582249259Sdim      (!UseFastNewTypeArray   && (op->type() != T_OBJECT && op->type() != T_ARRAY))) {
1583249259Sdim    __ jmp(*op->stub()->entry());
1584249259Sdim  } else {
1585249259Sdim    Register tmp1 = op->tmp1()->as_register();
1586249259Sdim    Register tmp2 = op->tmp2()->as_register();
1587249259Sdim    Register tmp3 = op->tmp3()->as_register();
1588249259Sdim    if (len == tmp1) {
1589249259Sdim      tmp1 = tmp3;
1590249259Sdim    } else if (len == tmp2) {
1591249259Sdim      tmp2 = tmp3;
1592249259Sdim    } else if (len == tmp3) {
1593249259Sdim      // everything is ok
1594249259Sdim    } else {
1595249259Sdim      __ mov(tmp3, len);
1596249259Sdim    }
1597249259Sdim    __ allocate_array(op->obj()->as_register(),
1598249259Sdim                      len,
1599249259Sdim                      tmp1,
1600249259Sdim                      tmp2,
1601249259Sdim                      arrayOopDesc::header_size(op->type()),
1602249259Sdim                      array_element_size(op->type()),
1603249259Sdim                      op->klass()->as_register(),
1604249259Sdim                      *op->stub()->entry());
1605249259Sdim  }
1606249259Sdim  __ bind(*op->stub()->continuation());
1607249259Sdim}
1608249259Sdim
1609249259Sdimvoid LIR_Assembler::type_profile_helper(Register mdo,
1610249259Sdim                                        ciMethodData *md, ciProfileData *data,
1611249259Sdim                                        Register recv, Label* update_done) {
1612249259Sdim  for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) {
1613249259Sdim    Label next_test;
1614249259Sdim    // See if the receiver is receiver[n].
1615249259Sdim    __ cmpptr(recv, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i))));
1616249259Sdim    __ jccb(Assembler::notEqual, next_test);
1617249259Sdim    Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)));
1618249259Sdim    __ addptr(data_addr, DataLayout::counter_increment);
1619249259Sdim    __ jmp(*update_done);
1620249259Sdim    __ bind(next_test);
1621249259Sdim  }
1622249259Sdim
1623249259Sdim  // Didn't find receiver; find next empty slot and fill it in
1624249259Sdim  for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) {
1625249259Sdim    Label next_test;
1626249259Sdim    Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)));
1627249259Sdim    __ cmpptr(recv_addr, (intptr_t)NULL_WORD);
1628249259Sdim    __ jccb(Assembler::notEqual, next_test);
1629249259Sdim    __ movptr(recv_addr, recv);
1630249259Sdim    __ movptr(Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))), DataLayout::counter_increment);
1631249259Sdim    __ jmp(*update_done);
1632249259Sdim    __ bind(next_test);
1633249259Sdim  }
1634249259Sdim}
1635249259Sdim
1636249259Sdimvoid LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null) {
1637249259Sdim  // we always need a stub for the failure case.
1638249259Sdim  CodeStub* stub = op->stub();
1639249259Sdim  Register obj = op->object()->as_register();
1640249259Sdim  Register k_RInfo = op->tmp1()->as_register();
1641249259Sdim  Register klass_RInfo = op->tmp2()->as_register();
1642249259Sdim  Register dst = op->result_opr()->as_register();
1643249259Sdim  ciKlass* k = op->klass();
1644249259Sdim  Register Rtmp1 = noreg;
1645249259Sdim
1646249259Sdim  // check if it needs to be profiled
1647249259Sdim  ciMethodData* md;
1648249259Sdim  ciProfileData* data;
1649249259Sdim
1650249259Sdim  if (op->should_profile()) {
1651249259Sdim    ciMethod* method = op->profiled_method();
1652249259Sdim    assert(method != NULL, "Should have method");
1653249259Sdim    int bci = op->profiled_bci();
1654249259Sdim    md = method->method_data_or_null();
1655249259Sdim    assert(md != NULL, "Sanity");
1656249259Sdim    data = md->bci_to_data(bci);
1657249259Sdim    assert(data != NULL,                "need data for type check");
1658249259Sdim    assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
1659249259Sdim  }
1660249259Sdim  Label profile_cast_success, profile_cast_failure;
1661249259Sdim  Label *success_target = op->should_profile() ? &profile_cast_success : success;
1662249259Sdim  Label *failure_target = op->should_profile() ? &profile_cast_failure : failure;
1663249259Sdim
1664249259Sdim  if (obj == k_RInfo) {
1665249259Sdim    k_RInfo = dst;
1666249259Sdim  } else if (obj == klass_RInfo) {
1667249259Sdim    klass_RInfo = dst;
1668249259Sdim  }
1669249259Sdim  if (k->is_loaded() && !UseCompressedOops) {
1670249259Sdim    select_different_registers(obj, dst, k_RInfo, klass_RInfo);
1671249259Sdim  } else {
1672249259Sdim    Rtmp1 = op->tmp3()->as_register();
1673249259Sdim    select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1);
1674249259Sdim  }
1675249259Sdim
1676249259Sdim  assert_different_registers(obj, k_RInfo, klass_RInfo);
1677249259Sdim  if (!k->is_loaded()) {
1678249259Sdim    jobject2reg_with_patching(k_RInfo, op->info_for_patch());
1679249259Sdim  } else {
1680249259Sdim#ifdef _LP64
1681249259Sdim    __ movoop(k_RInfo, k->constant_encoding());
1682249259Sdim#endif // _LP64
1683263508Sdim  }
1684263508Sdim  assert(obj != k_RInfo, "must be different");
1685263508Sdim
1686263508Sdim  __ cmpptr(obj, (int32_t)NULL_WORD);
1687263508Sdim  if (op->should_profile()) {
1688263508Sdim    Label not_null;
1689263508Sdim    __ jccb(Assembler::notEqual, not_null);
1690249259Sdim    // Object is null; update MDO and exit
1691249259Sdim    Register mdo  = klass_RInfo;
1692249259Sdim    __ movoop(mdo, md->constant_encoding());
1693249259Sdim    Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
1694249259Sdim    int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
1695249259Sdim    __ orl(data_addr, header_bits);
1696249259Sdim    __ jmp(*obj_is_null);
1697249259Sdim    __ bind(not_null);
1698249259Sdim  } else {
1699249259Sdim    __ jcc(Assembler::equal, *obj_is_null);
1700249259Sdim  }
1701249259Sdim  __ verify_oop(obj);
1702249259Sdim
1703249259Sdim  if (op->fast_check()) {
1704249259Sdim    // get object class
1705249259Sdim    // not a safepoint as obj null check happens earlier
1706249259Sdim#ifdef _LP64
1707249259Sdim    if (UseCompressedOops) {
1708249259Sdim      __ load_klass(Rtmp1, obj);
1709249259Sdim      __ cmpptr(k_RInfo, Rtmp1);
1710249259Sdim    } else {
1711249259Sdim      __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
1712249259Sdim    }
1713249259Sdim#else
1714249259Sdim    if (k->is_loaded()) {
1715249259Sdim      __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding());
1716249259Sdim    } else {
1717249259Sdim      __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
1718249259Sdim    }
1719249259Sdim#endif
1720249259Sdim    __ jcc(Assembler::notEqual, *failure_target);
1721249259Sdim    // successful cast, fall through to profile or jump
1722249259Sdim  } else {
1723249259Sdim    // get object class
1724249259Sdim    // not a safepoint as obj null check happens earlier
1725249259Sdim    __ load_klass(klass_RInfo, obj);
1726249259Sdim    if (k->is_loaded()) {
1727249259Sdim      // See if we get an immediate positive hit
1728249259Sdim#ifdef _LP64
1729249259Sdim      __ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset()));
1730249259Sdim#else
1731249259Sdim      __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding());
1732249259Sdim#endif // _LP64
1733249259Sdim      if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) {
1734249259Sdim        __ jcc(Assembler::notEqual, *failure_target);
1735249259Sdim        // successful cast, fall through to profile or jump
1736249259Sdim      } else {
1737249259Sdim        // See if we get an immediate positive hit
1738249259Sdim        __ jcc(Assembler::equal, *success_target);
1739249259Sdim        // check for self
1740249259Sdim#ifdef _LP64
1741249259Sdim        __ cmpptr(klass_RInfo, k_RInfo);
1742249259Sdim#else
1743249259Sdim        __ cmpoop(klass_RInfo, k->constant_encoding());
1744249259Sdim#endif // _LP64
1745249259Sdim        __ jcc(Assembler::equal, *success_target);
1746249259Sdim
1747249259Sdim        __ push(klass_RInfo);
1748249259Sdim#ifdef _LP64
1749249259Sdim        __ push(k_RInfo);
1750249259Sdim#else
1751249259Sdim        __ pushoop(k->constant_encoding());
1752249259Sdim#endif // _LP64
1753249259Sdim        __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
1754249259Sdim        __ pop(klass_RInfo);
1755249259Sdim        __ pop(klass_RInfo);
1756249259Sdim        // result is a boolean
1757249259Sdim        __ cmpl(klass_RInfo, 0);
1758249259Sdim        __ jcc(Assembler::equal, *failure_target);
1759249259Sdim        // successful cast, fall through to profile or jump
1760249259Sdim      }
1761249259Sdim    } else {
1762249259Sdim      // perform the fast part of the checking logic
1763249259Sdim      __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL);
1764249259Sdim      // call out-of-line instance of __ check_klass_subtype_slow_path(...):
1765249259Sdim      __ push(klass_RInfo);
1766249259Sdim      __ push(k_RInfo);
1767249259Sdim      __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
1768249259Sdim      __ pop(klass_RInfo);
1769249259Sdim      __ pop(k_RInfo);
1770249259Sdim      // result is a boolean
1771249259Sdim      __ cmpl(k_RInfo, 0);
1772249259Sdim      __ jcc(Assembler::equal, *failure_target);
1773249259Sdim      // successful cast, fall through to profile or jump
1774249259Sdim    }
1775249259Sdim  }
1776249259Sdim  if (op->should_profile()) {
1777249259Sdim    Register mdo  = klass_RInfo, recv = k_RInfo;
1778249259Sdim    __ bind(profile_cast_success);
1779249259Sdim    __ movoop(mdo, md->constant_encoding());
1780249259Sdim    __ load_klass(recv, obj);
1781249259Sdim    Label update_done;
1782249259Sdim    type_profile_helper(mdo, md, data, recv, success);
1783249259Sdim    __ jmp(*success);
1784249259Sdim
1785249259Sdim    __ bind(profile_cast_failure);
1786249259Sdim    __ movoop(mdo, md->constant_encoding());
1787249259Sdim    Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
1788249259Sdim    __ subptr(counter_addr, DataLayout::counter_increment);
1789249259Sdim    __ jmp(*failure);
1790249259Sdim  }
1791249259Sdim  __ jmp(*success);
1792249259Sdim}
1793249259Sdim
1794249259Sdim
1795249259Sdimvoid LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
1796249259Sdim  LIR_Code code = op->code();
1797249259Sdim  if (code == lir_store_check) {
1798249259Sdim    Register value = op->object()->as_register();
1799249259Sdim    Register array = op->array()->as_register();
1800249259Sdim    Register k_RInfo = op->tmp1()->as_register();
1801249259Sdim    Register klass_RInfo = op->tmp2()->as_register();
1802249259Sdim    Register Rtmp1 = op->tmp3()->as_register();
1803249259Sdim
1804249259Sdim    CodeStub* stub = op->stub();
1805249259Sdim
1806249259Sdim    // check if it needs to be profiled
1807249259Sdim    ciMethodData* md;
1808249259Sdim    ciProfileData* data;
1809249259Sdim
1810249259Sdim    if (op->should_profile()) {
1811249259Sdim      ciMethod* method = op->profiled_method();
1812249259Sdim      assert(method != NULL, "Should have method");
1813249259Sdim      int bci = op->profiled_bci();
1814249259Sdim      md = method->method_data_or_null();
1815249259Sdim      assert(md != NULL, "Sanity");
1816249259Sdim      data = md->bci_to_data(bci);
1817249259Sdim      assert(data != NULL,                "need data for type check");
1818249259Sdim      assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
1819249259Sdim    }
1820249259Sdim    Label profile_cast_success, profile_cast_failure, done;
1821249259Sdim    Label *success_target = op->should_profile() ? &profile_cast_success : &done;
1822249259Sdim    Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry();
1823249259Sdim
1824249259Sdim    __ cmpptr(value, (int32_t)NULL_WORD);
1825249259Sdim    if (op->should_profile()) {
1826249259Sdim      Label not_null;
1827249259Sdim      __ jccb(Assembler::notEqual, not_null);
1828249259Sdim      // Object is null; update MDO and exit
1829249259Sdim      Register mdo  = klass_RInfo;
1830249259Sdim      __ movoop(mdo, md->constant_encoding());
1831249259Sdim      Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
1832249259Sdim      int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
1833249259Sdim      __ orl(data_addr, header_bits);
1834249259Sdim      __ jmp(done);
1835249259Sdim      __ bind(not_null);
1836249259Sdim    } else {
1837249259Sdim      __ jcc(Assembler::equal, done);
1838249259Sdim    }
1839249259Sdim
1840249259Sdim    add_debug_info_for_null_check_here(op->info_for_exception());
1841249259Sdim    __ load_klass(k_RInfo, array);
1842249259Sdim    __ load_klass(klass_RInfo, value);
1843249259Sdim
1844249259Sdim    // get instance klass (it's already uncompressed)
1845249259Sdim    __ movptr(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)));
1846249259Sdim    // perform the fast part of the checking logic
1847249259Sdim    __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL);
1848249259Sdim    // call out-of-line instance of __ check_klass_subtype_slow_path(...):
1849249259Sdim    __ push(klass_RInfo);
1850249259Sdim    __ push(k_RInfo);
1851249259Sdim    __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
1852249259Sdim    __ pop(klass_RInfo);
1853249259Sdim    __ pop(k_RInfo);
1854249259Sdim    // result is a boolean
1855249259Sdim    __ cmpl(k_RInfo, 0);
1856249259Sdim    __ jcc(Assembler::equal, *failure_target);
1857249259Sdim    // fall through to the success case
1858249259Sdim
1859249259Sdim    if (op->should_profile()) {
1860249259Sdim      Register mdo  = klass_RInfo, recv = k_RInfo;
1861249259Sdim      __ bind(profile_cast_success);
1862249259Sdim      __ movoop(mdo, md->constant_encoding());
1863249259Sdim      __ load_klass(recv, value);
1864249259Sdim      Label update_done;
1865249259Sdim      type_profile_helper(mdo, md, data, recv, &done);
1866249259Sdim      __ jmpb(done);
1867249259Sdim
1868249259Sdim      __ bind(profile_cast_failure);
1869249259Sdim      __ movoop(mdo, md->constant_encoding());
1870249259Sdim      Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
1871249259Sdim      __ subptr(counter_addr, DataLayout::counter_increment);
1872249259Sdim      __ jmp(*stub->entry());
1873249259Sdim    }
1874249259Sdim
1875249259Sdim    __ bind(done);
1876249259Sdim  } else
1877249259Sdim    if (code == lir_checkcast) {
1878249259Sdim      Register obj = op->object()->as_register();
1879249259Sdim      Register dst = op->result_opr()->as_register();
1880249259Sdim      Label success;
1881249259Sdim      emit_typecheck_helper(op, &success, op->stub()->entry(), &success);
1882249259Sdim      __ bind(success);
1883249259Sdim      if (dst != obj) {
1884249259Sdim        __ mov(dst, obj);
1885249259Sdim      }
1886249259Sdim    } else
1887249259Sdim      if (code == lir_instanceof) {
1888249259Sdim        Register obj = op->object()->as_register();
1889249259Sdim        Register dst = op->result_opr()->as_register();
1890249259Sdim        Label success, failure, done;
1891249259Sdim        emit_typecheck_helper(op, &success, &failure, &failure);
1892249259Sdim        __ bind(failure);
1893249259Sdim        __ xorptr(dst, dst);
1894249259Sdim        __ jmpb(done);
1895249259Sdim        __ bind(success);
1896249259Sdim        __ movptr(dst, 1);
1897249259Sdim        __ bind(done);
1898249259Sdim      } else {
1899249259Sdim        ShouldNotReachHere();
1900249259Sdim      }
1901249259Sdim
1902249259Sdim}
1903249259Sdim
1904249259Sdim
1905249259Sdimvoid LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) {
1906249259Sdim  if (LP64_ONLY(false &&) op->code() == lir_cas_long && VM_Version::supports_cx8()) {
1907249259Sdim    assert(op->cmp_value()->as_register_lo() == rax, "wrong register");
1908249259Sdim    assert(op->cmp_value()->as_register_hi() == rdx, "wrong register");
1909249259Sdim    assert(op->new_value()->as_register_lo() == rbx, "wrong register");
1910249259Sdim    assert(op->new_value()->as_register_hi() == rcx, "wrong register");
1911249259Sdim    Register addr = op->addr()->as_register();
1912249259Sdim    if (os::is_MP()) {
1913249259Sdim      __ lock();
1914249259Sdim    }
1915249259Sdim    NOT_LP64(__ cmpxchg8(Address(addr, 0)));
1916249259Sdim
1917249259Sdim  } else if (op->code() == lir_cas_int || op->code() == lir_cas_obj ) {
1918249259Sdim    NOT_LP64(assert(op->addr()->is_single_cpu(), "must be single");)
1919249259Sdim    Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo());
1920249259Sdim    Register newval = op->new_value()->as_register();
1921249259Sdim    Register cmpval = op->cmp_value()->as_register();
1922249259Sdim    assert(cmpval == rax, "wrong register");
1923249259Sdim    assert(newval != NULL, "new val must be register");
1924249259Sdim    assert(cmpval != newval, "cmp and new values must be in different registers");
1925249259Sdim    assert(cmpval != addr, "cmp and addr must be in different registers");
1926249259Sdim    assert(newval != addr, "new value and addr must be in different registers");
1927249259Sdim
1928249259Sdim    if ( op->code() == lir_cas_obj) {
1929249259Sdim#ifdef _LP64
1930249259Sdim      if (UseCompressedOops) {
1931249259Sdim        __ encode_heap_oop(cmpval);
1932249259Sdim        __ mov(rscratch1, newval);
1933249259Sdim        __ encode_heap_oop(rscratch1);
1934249259Sdim        if (os::is_MP()) {
1935249259Sdim          __ lock();
1936249259Sdim        }
1937249259Sdim        // cmpval (rax) is implicitly used by this instruction
1938249259Sdim        __ cmpxchgl(rscratch1, Address(addr, 0));
1939249259Sdim      } else
1940249259Sdim#endif
1941249259Sdim      {
1942249259Sdim        if (os::is_MP()) {
1943249259Sdim          __ lock();
1944249259Sdim        }
1945249259Sdim        __ cmpxchgptr(newval, Address(addr, 0));
1946249259Sdim      }
1947249259Sdim    } else {
1948249259Sdim      assert(op->code() == lir_cas_int, "lir_cas_int expected");
1949249259Sdim      if (os::is_MP()) {
1950249259Sdim        __ lock();
1951249259Sdim      }
1952249259Sdim      __ cmpxchgl(newval, Address(addr, 0));
1953249259Sdim    }
1954249259Sdim#ifdef _LP64
1955249259Sdim  } else if (op->code() == lir_cas_long) {
1956249259Sdim    Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo());
1957249259Sdim    Register newval = op->new_value()->as_register_lo();
1958249259Sdim    Register cmpval = op->cmp_value()->as_register_lo();
1959249259Sdim    assert(cmpval == rax, "wrong register");
1960249259Sdim    assert(newval != NULL, "new val must be register");
1961249259Sdim    assert(cmpval != newval, "cmp and new values must be in different registers");
1962249259Sdim    assert(cmpval != addr, "cmp and addr must be in different registers");
1963249259Sdim    assert(newval != addr, "new value and addr must be in different registers");
1964249259Sdim    if (os::is_MP()) {
1965249259Sdim      __ lock();
1966249259Sdim    }
1967249259Sdim    __ cmpxchgq(newval, Address(addr, 0));
1968249259Sdim#endif // _LP64
1969249259Sdim  } else {
1970249259Sdim    Unimplemented();
1971249259Sdim  }
1972249259Sdim}
1973249259Sdim
1974249259Sdimvoid LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type) {
1975249259Sdim  Assembler::Condition acond, ncond;
1976249259Sdim  switch (condition) {
1977249259Sdim    case lir_cond_equal:        acond = Assembler::equal;        ncond = Assembler::notEqual;     break;
1978249259Sdim    case lir_cond_notEqual:     acond = Assembler::notEqual;     ncond = Assembler::equal;        break;
1979249259Sdim    case lir_cond_less:         acond = Assembler::less;         ncond = Assembler::greaterEqual; break;
1980249259Sdim    case lir_cond_lessEqual:    acond = Assembler::lessEqual;    ncond = Assembler::greater;      break;
1981249259Sdim    case lir_cond_greaterEqual: acond = Assembler::greaterEqual; ncond = Assembler::less;         break;
1982263508Sdim    case lir_cond_greater:      acond = Assembler::greater;      ncond = Assembler::lessEqual;    break;
1983263508Sdim    case lir_cond_belowEqual:   acond = Assembler::belowEqual;   ncond = Assembler::above;        break;
1984263508Sdim    case lir_cond_aboveEqual:   acond = Assembler::aboveEqual;   ncond = Assembler::below;        break;
1985249259Sdim    default:                    ShouldNotReachHere();
1986249259Sdim  }
1987249259Sdim
1988263508Sdim  if (opr1->is_cpu_register()) {
1989263508Sdim    reg2reg(opr1, result);
1990263508Sdim  } else if (opr1->is_stack()) {
1991263508Sdim    stack2reg(opr1, result, result->type());
1992263508Sdim  } else if (opr1->is_constant()) {
1993263508Sdim    const2reg(opr1, result, lir_patch_none, NULL);
1994263508Sdim  } else {
1995263508Sdim    ShouldNotReachHere();
1996263508Sdim  }
1997263508Sdim
1998249259Sdim  if (VM_Version::supports_cmov() && !opr2->is_constant()) {
1999249259Sdim    // optimized version that does not require a branch
2000249259Sdim    if (opr2->is_single_cpu()) {
2001249259Sdim      assert(opr2->cpu_regnr() != result->cpu_regnr(), "opr2 already overwritten by previous move");
2002249259Sdim      __ cmov(ncond, result->as_register(), opr2->as_register());
2003249259Sdim    } else if (opr2->is_double_cpu()) {
2004249259Sdim      assert(opr2->cpu_regnrLo() != result->cpu_regnrLo() && opr2->cpu_regnrLo() != result->cpu_regnrHi(), "opr2 already overwritten by previous move");
2005249259Sdim      assert(opr2->cpu_regnrHi() != result->cpu_regnrLo() && opr2->cpu_regnrHi() != result->cpu_regnrHi(), "opr2 already overwritten by previous move");
2006249259Sdim      __ cmovptr(ncond, result->as_register_lo(), opr2->as_register_lo());
2007249259Sdim      NOT_LP64(__ cmovptr(ncond, result->as_register_hi(), opr2->as_register_hi());)
2008249259Sdim    } else if (opr2->is_single_stack()) {
2009249259Sdim      __ cmovl(ncond, result->as_register(), frame_map()->address_for_slot(opr2->single_stack_ix()));
2010249259Sdim    } else if (opr2->is_double_stack()) {
2011263508Sdim      __ cmovptr(ncond, result->as_register_lo(), frame_map()->address_for_slot(opr2->double_stack_ix(), lo_word_offset_in_bytes));
2012263508Sdim      NOT_LP64(__ cmovptr(ncond, result->as_register_hi(), frame_map()->address_for_slot(opr2->double_stack_ix(), hi_word_offset_in_bytes));)
2013263508Sdim    } else {
2014263508Sdim      ShouldNotReachHere();
2015263508Sdim    }
2016263508Sdim
2017263508Sdim  } else {
2018263508Sdim    Label skip;
2019249259Sdim    __ jcc (acond, skip);
2020249259Sdim    if (opr2->is_cpu_register()) {
2021249259Sdim      reg2reg(opr2, result);
2022249259Sdim    } else if (opr2->is_stack()) {
2023249259Sdim      stack2reg(opr2, result, result->type());
2024249259Sdim    } else if (opr2->is_constant()) {
2025249259Sdim      const2reg(opr2, result, lir_patch_none, NULL);
2026249259Sdim    } else {
2027249259Sdim      ShouldNotReachHere();
2028249259Sdim    }
2029249259Sdim    __ bind(skip);
2030249259Sdim  }
2031249259Sdim}
2032249259Sdim
2033249259Sdim
2034249259Sdimvoid LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info, bool pop_fpu_stack) {
2035249259Sdim  assert(info == NULL, "should never be used, idiv/irem and ldiv/lrem not handled by this method");
2036249259Sdim
2037249259Sdim  if (left->is_single_cpu()) {
2038249259Sdim    assert(left == dest, "left and dest must be equal");
2039249259Sdim    Register lreg = left->as_register();
2040249259Sdim
2041249259Sdim    if (right->is_single_cpu()) {
2042249259Sdim      // cpu register - cpu register
2043249259Sdim      Register rreg = right->as_register();
2044249259Sdim      switch (code) {
2045249259Sdim        case lir_add: __ addl (lreg, rreg); break;
2046249259Sdim        case lir_sub: __ subl (lreg, rreg); break;
2047249259Sdim        case lir_mul: __ imull(lreg, rreg); break;
2048249259Sdim        default:      ShouldNotReachHere();
2049249259Sdim      }
2050249259Sdim
2051249259Sdim    } else if (right->is_stack()) {
2052249259Sdim      // cpu register - stack
2053249259Sdim      Address raddr = frame_map()->address_for_slot(right->single_stack_ix());
2054249259Sdim      switch (code) {
2055249259Sdim        case lir_add: __ addl(lreg, raddr); break;
2056249259Sdim        case lir_sub: __ subl(lreg, raddr); break;
2057249259Sdim        default:      ShouldNotReachHere();
2058249259Sdim      }
2059249259Sdim
2060249259Sdim    } else if (right->is_constant()) {
2061249259Sdim      // cpu register - constant
2062249259Sdim      jint c = right->as_constant_ptr()->as_jint();
2063249259Sdim      switch (code) {
2064249259Sdim        case lir_add: {
2065249259Sdim          __ incrementl(lreg, c);
2066249259Sdim          break;
2067249259Sdim        }
2068249259Sdim        case lir_sub: {
2069249259Sdim          __ decrementl(lreg, c);
2070249259Sdim          break;
2071249259Sdim        }
2072249259Sdim        default: ShouldNotReachHere();
2073249259Sdim      }
2074249259Sdim
2075249259Sdim    } else {
2076249259Sdim      ShouldNotReachHere();
2077249259Sdim    }
2078249259Sdim
2079249259Sdim  } else if (left->is_double_cpu()) {
2080249259Sdim    assert(left == dest, "left and dest must be equal");
2081249259Sdim    Register lreg_lo = left->as_register_lo();
2082249259Sdim    Register lreg_hi = left->as_register_hi();
2083249259Sdim
2084249259Sdim    if (right->is_double_cpu()) {
2085249259Sdim      // cpu register - cpu register
2086249259Sdim      Register rreg_lo = right->as_register_lo();
2087249259Sdim      Register rreg_hi = right->as_register_hi();
2088249259Sdim      NOT_LP64(assert_different_registers(lreg_lo, lreg_hi, rreg_lo, rreg_hi));
2089249259Sdim      LP64_ONLY(assert_different_registers(lreg_lo, rreg_lo));
2090249259Sdim      switch (code) {
2091249259Sdim        case lir_add:
2092249259Sdim          __ addptr(lreg_lo, rreg_lo);
2093249259Sdim          NOT_LP64(__ adcl(lreg_hi, rreg_hi));
2094249259Sdim          break;
2095249259Sdim        case lir_sub:
2096249259Sdim          __ subptr(lreg_lo, rreg_lo);
2097249259Sdim          NOT_LP64(__ sbbl(lreg_hi, rreg_hi));
2098249259Sdim          break;
2099249259Sdim        case lir_mul:
2100249259Sdim#ifdef _LP64
2101249259Sdim          __ imulq(lreg_lo, rreg_lo);
2102249259Sdim#else
2103249259Sdim          assert(lreg_lo == rax && lreg_hi == rdx, "must be");
2104249259Sdim          __ imull(lreg_hi, rreg_lo);
2105249259Sdim          __ imull(rreg_hi, lreg_lo);
2106249259Sdim          __ addl (rreg_hi, lreg_hi);
2107249259Sdim          __ mull (rreg_lo);
2108249259Sdim          __ addl (lreg_hi, rreg_hi);
2109249259Sdim#endif // _LP64
2110249259Sdim          break;
2111249259Sdim        default:
2112249259Sdim          ShouldNotReachHere();
2113249259Sdim      }
2114249259Sdim
2115249259Sdim    } else if (right->is_constant()) {
2116249259Sdim      // cpu register - constant
2117249259Sdim#ifdef _LP64
2118249259Sdim      jlong c = right->as_constant_ptr()->as_jlong_bits();
2119249259Sdim      __ movptr(r10, (intptr_t) c);
2120249259Sdim      switch (code) {
2121249259Sdim        case lir_add:
2122249259Sdim          __ addptr(lreg_lo, r10);
2123249259Sdim          break;
2124249259Sdim        case lir_sub:
2125249259Sdim          __ subptr(lreg_lo, r10);
2126249259Sdim          break;
2127249259Sdim        default:
2128249259Sdim          ShouldNotReachHere();
2129249259Sdim      }
2130249259Sdim#else
2131249259Sdim      jint c_lo = right->as_constant_ptr()->as_jint_lo();
2132249259Sdim      jint c_hi = right->as_constant_ptr()->as_jint_hi();
2133249259Sdim      switch (code) {
2134249259Sdim        case lir_add:
2135249259Sdim          __ addptr(lreg_lo, c_lo);
2136249259Sdim          __ adcl(lreg_hi, c_hi);
2137249259Sdim          break;
2138249259Sdim        case lir_sub:
2139249259Sdim          __ subptr(lreg_lo, c_lo);
2140249259Sdim          __ sbbl(lreg_hi, c_hi);
2141249259Sdim          break;
2142249259Sdim        default:
2143249259Sdim          ShouldNotReachHere();
2144249259Sdim      }
2145249259Sdim#endif // _LP64
2146249259Sdim
2147249259Sdim    } else {
2148249259Sdim      ShouldNotReachHere();
2149249259Sdim    }
2150249259Sdim
2151249259Sdim  } else if (left->is_single_xmm()) {
2152249259Sdim    assert(left == dest, "left and dest must be equal");
2153249259Sdim    XMMRegister lreg = left->as_xmm_float_reg();
2154249259Sdim
2155249259Sdim    if (right->is_single_xmm()) {
2156249259Sdim      XMMRegister rreg = right->as_xmm_float_reg();
2157249259Sdim      switch (code) {
2158249259Sdim        case lir_add: __ addss(lreg, rreg);  break;
2159249259Sdim        case lir_sub: __ subss(lreg, rreg);  break;
2160249259Sdim        case lir_mul_strictfp: // fall through
2161249259Sdim        case lir_mul: __ mulss(lreg, rreg);  break;
2162249259Sdim        case lir_div_strictfp: // fall through
2163249259Sdim        case lir_div: __ divss(lreg, rreg);  break;
2164249259Sdim        default: ShouldNotReachHere();
2165249259Sdim      }
2166249259Sdim    } else {
2167249259Sdim      Address raddr;
2168249259Sdim      if (right->is_single_stack()) {
2169249259Sdim        raddr = frame_map()->address_for_slot(right->single_stack_ix());
2170249259Sdim      } else if (right->is_constant()) {
2171249259Sdim        // hack for now
2172249259Sdim        raddr = __ as_Address(InternalAddress(float_constant(right->as_jfloat())));
2173249259Sdim      } else {
2174249259Sdim        ShouldNotReachHere();
2175249259Sdim      }
2176249259Sdim      switch (code) {
2177249259Sdim        case lir_add: __ addss(lreg, raddr);  break;
2178249259Sdim        case lir_sub: __ subss(lreg, raddr);  break;
2179249259Sdim        case lir_mul_strictfp: // fall through
2180249259Sdim        case lir_mul: __ mulss(lreg, raddr);  break;
2181249259Sdim        case lir_div_strictfp: // fall through
2182249259Sdim        case lir_div: __ divss(lreg, raddr);  break;
2183249259Sdim        default: ShouldNotReachHere();
2184249259Sdim      }
2185249259Sdim    }
2186249259Sdim
2187249259Sdim  } else if (left->is_double_xmm()) {
2188249259Sdim    assert(left == dest, "left and dest must be equal");
2189249259Sdim
2190249259Sdim    XMMRegister lreg = left->as_xmm_double_reg();
2191249259Sdim    if (right->is_double_xmm()) {
2192249259Sdim      XMMRegister rreg = right->as_xmm_double_reg();
2193249259Sdim      switch (code) {
2194249259Sdim        case lir_add: __ addsd(lreg, rreg);  break;
2195249259Sdim        case lir_sub: __ subsd(lreg, rreg);  break;
2196249259Sdim        case lir_mul_strictfp: // fall through
2197249259Sdim        case lir_mul: __ mulsd(lreg, rreg);  break;
2198249259Sdim        case lir_div_strictfp: // fall through
2199249259Sdim        case lir_div: __ divsd(lreg, rreg);  break;
2200249259Sdim        default: ShouldNotReachHere();
2201249259Sdim      }
2202249259Sdim    } else {
2203249259Sdim      Address raddr;
2204249259Sdim      if (right->is_double_stack()) {
2205249259Sdim        raddr = frame_map()->address_for_slot(right->double_stack_ix());
2206249259Sdim      } else if (right->is_constant()) {
2207249259Sdim        // hack for now
2208249259Sdim        raddr = __ as_Address(InternalAddress(double_constant(right->as_jdouble())));
2209249259Sdim      } else {
2210249259Sdim        ShouldNotReachHere();
2211249259Sdim      }
2212249259Sdim      switch (code) {
2213249259Sdim        case lir_add: __ addsd(lreg, raddr);  break;
2214249259Sdim        case lir_sub: __ subsd(lreg, raddr);  break;
2215249259Sdim        case lir_mul_strictfp: // fall through
2216249259Sdim        case lir_mul: __ mulsd(lreg, raddr);  break;
2217249259Sdim        case lir_div_strictfp: // fall through
2218249259Sdim        case lir_div: __ divsd(lreg, raddr);  break;
2219249259Sdim        default: ShouldNotReachHere();
2220249259Sdim      }
2221249259Sdim    }
2222249259Sdim
2223249259Sdim  } else if (left->is_single_fpu()) {
2224249259Sdim    assert(dest->is_single_fpu(),  "fpu stack allocation required");
2225249259Sdim
2226249259Sdim    if (right->is_single_fpu()) {
2227249259Sdim      arith_fpu_implementation(code, left->fpu_regnr(), right->fpu_regnr(), dest->fpu_regnr(), pop_fpu_stack);
2228249259Sdim
2229249259Sdim    } else {
2230249259Sdim      assert(left->fpu_regnr() == 0, "left must be on TOS");
2231249259Sdim      assert(dest->fpu_regnr() == 0, "dest must be on TOS");
2232249259Sdim
2233249259Sdim      Address raddr;
2234249259Sdim      if (right->is_single_stack()) {
2235249259Sdim        raddr = frame_map()->address_for_slot(right->single_stack_ix());
2236249259Sdim      } else if (right->is_constant()) {
2237249259Sdim        address const_addr = float_constant(right->as_jfloat());
2238249259Sdim        assert(const_addr != NULL, "incorrect float/double constant maintainance");
2239249259Sdim        // hack for now
2240249259Sdim        raddr = __ as_Address(InternalAddress(const_addr));
2241249259Sdim      } else {
2242249259Sdim        ShouldNotReachHere();
2243249259Sdim      }
2244249259Sdim
2245249259Sdim      switch (code) {
2246249259Sdim        case lir_add: __ fadd_s(raddr); break;
2247249259Sdim        case lir_sub: __ fsub_s(raddr); break;
2248249259Sdim        case lir_mul_strictfp: // fall through
2249249259Sdim        case lir_mul: __ fmul_s(raddr); break;
2250249259Sdim        case lir_div_strictfp: // fall through
2251249259Sdim        case lir_div: __ fdiv_s(raddr); break;
2252249259Sdim        default:      ShouldNotReachHere();
2253249259Sdim      }
2254249259Sdim    }
2255249259Sdim
2256249259Sdim  } else if (left->is_double_fpu()) {
2257249259Sdim    assert(dest->is_double_fpu(),  "fpu stack allocation required");
2258249259Sdim
2259249259Sdim    if (code == lir_mul_strictfp || code == lir_div_strictfp) {
2260249259Sdim      // Double values require special handling for strictfp mul/div on x86
2261249259Sdim      __ fld_x(ExternalAddress(StubRoutines::addr_fpu_subnormal_bias1()));
2262249259Sdim      __ fmulp(left->fpu_regnrLo() + 1);
2263249259Sdim    }
2264249259Sdim
2265249259Sdim    if (right->is_double_fpu()) {
2266249259Sdim      arith_fpu_implementation(code, left->fpu_regnrLo(), right->fpu_regnrLo(), dest->fpu_regnrLo(), pop_fpu_stack);
2267249259Sdim
2268249259Sdim    } else {
2269249259Sdim      assert(left->fpu_regnrLo() == 0, "left must be on TOS");
2270249259Sdim      assert(dest->fpu_regnrLo() == 0, "dest must be on TOS");
2271249259Sdim
2272249259Sdim      Address raddr;
2273249259Sdim      if (right->is_double_stack()) {
2274249259Sdim        raddr = frame_map()->address_for_slot(right->double_stack_ix());
2275249259Sdim      } else if (right->is_constant()) {
2276249259Sdim        // hack for now
2277249259Sdim        raddr = __ as_Address(InternalAddress(double_constant(right->as_jdouble())));
2278249259Sdim      } else {
2279249259Sdim        ShouldNotReachHere();
2280249259Sdim      }
2281249259Sdim
2282249259Sdim      switch (code) {
2283249259Sdim        case lir_add: __ fadd_d(raddr); break;
2284249259Sdim        case lir_sub: __ fsub_d(raddr); break;
2285249259Sdim        case lir_mul_strictfp: // fall through
2286249259Sdim        case lir_mul: __ fmul_d(raddr); break;
2287249259Sdim        case lir_div_strictfp: // fall through
2288249259Sdim        case lir_div: __ fdiv_d(raddr); break;
2289249259Sdim        default: ShouldNotReachHere();
2290249259Sdim      }
2291249259Sdim    }
2292249259Sdim
2293249259Sdim    if (code == lir_mul_strictfp || code == lir_div_strictfp) {
2294249259Sdim      // Double values require special handling for strictfp mul/div on x86
2295249259Sdim      __ fld_x(ExternalAddress(StubRoutines::addr_fpu_subnormal_bias2()));
2296249259Sdim      __ fmulp(dest->fpu_regnrLo() + 1);
2297249259Sdim    }
2298249259Sdim
2299249259Sdim  } else if (left->is_single_stack() || left->is_address()) {
2300249259Sdim    assert(left == dest, "left and dest must be equal");
2301249259Sdim
2302249259Sdim    Address laddr;
2303249259Sdim    if (left->is_single_stack()) {
2304249259Sdim      laddr = frame_map()->address_for_slot(left->single_stack_ix());
2305249259Sdim    } else if (left->is_address()) {
2306249259Sdim      laddr = as_Address(left->as_address_ptr());
2307249259Sdim    } else {
2308249259Sdim      ShouldNotReachHere();
2309249259Sdim    }
2310249259Sdim
2311249259Sdim    if (right->is_single_cpu()) {
2312249259Sdim      Register rreg = right->as_register();
2313249259Sdim      switch (code) {
2314249259Sdim        case lir_add: __ addl(laddr, rreg); break;
2315249259Sdim        case lir_sub: __ subl(laddr, rreg); break;
2316249259Sdim        default:      ShouldNotReachHere();
2317249259Sdim      }
2318249259Sdim    } else if (right->is_constant()) {
2319249259Sdim      jint c = right->as_constant_ptr()->as_jint();
2320249259Sdim      switch (code) {
2321249259Sdim        case lir_add: {
2322249259Sdim          __ incrementl(laddr, c);
2323249259Sdim          break;
2324249259Sdim        }
2325249259Sdim        case lir_sub: {
2326249259Sdim          __ decrementl(laddr, c);
2327249259Sdim          break;
2328249259Sdim        }
2329249259Sdim        default: ShouldNotReachHere();
2330249259Sdim      }
2331249259Sdim    } else {
2332249259Sdim      ShouldNotReachHere();
2333249259Sdim    }
2334249259Sdim
2335249259Sdim  } else {
2336249259Sdim    ShouldNotReachHere();
2337249259Sdim  }
2338249259Sdim}
2339249259Sdim
2340249259Sdimvoid LIR_Assembler::arith_fpu_implementation(LIR_Code code, int left_index, int right_index, int dest_index, bool pop_fpu_stack) {
2341249259Sdim  assert(pop_fpu_stack  || (left_index     == dest_index || right_index     == dest_index), "invalid LIR");
2342249259Sdim  assert(!pop_fpu_stack || (left_index - 1 == dest_index || right_index - 1 == dest_index), "invalid LIR");
2343249259Sdim  assert(left_index == 0 || right_index == 0, "either must be on top of stack");
2344249259Sdim
2345249259Sdim  bool left_is_tos = (left_index == 0);
2346249259Sdim  bool dest_is_tos = (dest_index == 0);
2347249259Sdim  int non_tos_index = (left_is_tos ? right_index : left_index);
2348249259Sdim
2349249259Sdim  switch (code) {
2350249259Sdim    case lir_add:
2351249259Sdim      if (pop_fpu_stack)       __ faddp(non_tos_index);
2352249259Sdim      else if (dest_is_tos)    __ fadd (non_tos_index);
2353249259Sdim      else                     __ fadda(non_tos_index);
2354249259Sdim      break;
2355249259Sdim
2356249259Sdim    case lir_sub:
2357249259Sdim      if (left_is_tos) {
2358249259Sdim        if (pop_fpu_stack)     __ fsubrp(non_tos_index);
2359249259Sdim        else if (dest_is_tos)  __ fsub  (non_tos_index);
2360249259Sdim        else                   __ fsubra(non_tos_index);
2361249259Sdim      } else {
2362249259Sdim        if (pop_fpu_stack)     __ fsubp (non_tos_index);
2363249259Sdim        else if (dest_is_tos)  __ fsubr (non_tos_index);
2364249259Sdim        else                   __ fsuba (non_tos_index);
2365249259Sdim      }
2366249259Sdim      break;
2367249259Sdim
2368249259Sdim    case lir_mul_strictfp: // fall through
2369249259Sdim    case lir_mul:
2370249259Sdim      if (pop_fpu_stack)       __ fmulp(non_tos_index);
2371249259Sdim      else if (dest_is_tos)    __ fmul (non_tos_index);
2372249259Sdim      else                     __ fmula(non_tos_index);
2373249259Sdim      break;
2374249259Sdim
2375249259Sdim    case lir_div_strictfp: // fall through
2376249259Sdim    case lir_div:
2377249259Sdim      if (left_is_tos) {
2378249259Sdim        if (pop_fpu_stack)     __ fdivrp(non_tos_index);
2379249259Sdim        else if (dest_is_tos)  __ fdiv  (non_tos_index);
2380249259Sdim        else                   __ fdivra(non_tos_index);
2381249259Sdim      } else {
2382249259Sdim        if (pop_fpu_stack)     __ fdivp (non_tos_index);
2383249259Sdim        else if (dest_is_tos)  __ fdivr (non_tos_index);
2384249259Sdim        else                   __ fdiva (non_tos_index);
2385249259Sdim      }
2386249259Sdim      break;
2387249259Sdim
2388249259Sdim    case lir_rem:
2389249259Sdim      assert(left_is_tos && dest_is_tos && right_index == 1, "must be guaranteed by FPU stack allocation");
2390249259Sdim      __ fremr(noreg);
2391249259Sdim      break;
2392249259Sdim
2393249259Sdim    default:
2394249259Sdim      ShouldNotReachHere();
2395249259Sdim  }
2396249259Sdim}
2397249259Sdim
2398249259Sdim
2399249259Sdimvoid LIR_Assembler::intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr unused, LIR_Opr dest, LIR_Op* op) {
2400249259Sdim  if (value->is_double_xmm()) {
2401249259Sdim    switch(code) {
2402249259Sdim      case lir_abs :
2403249259Sdim        {
2404249259Sdim          if (dest->as_xmm_double_reg() != value->as_xmm_double_reg()) {
2405249259Sdim            __ movdbl(dest->as_xmm_double_reg(), value->as_xmm_double_reg());
2406249259Sdim          }
2407249259Sdim          __ andpd(dest->as_xmm_double_reg(),
2408249259Sdim                    ExternalAddress((address)double_signmask_pool));
2409249259Sdim        }
2410249259Sdim        break;
2411249259Sdim
2412249259Sdim      case lir_sqrt: __ sqrtsd(dest->as_xmm_double_reg(), value->as_xmm_double_reg()); break;
2413249259Sdim      // all other intrinsics are not available in the SSE instruction set, so FPU is used
2414249259Sdim      default      : ShouldNotReachHere();
2415249259Sdim    }
2416249259Sdim
2417249259Sdim  } else if (value->is_double_fpu()) {
2418249259Sdim    assert(value->fpu_regnrLo() == 0 && dest->fpu_regnrLo() == 0, "both must be on TOS");
2419249259Sdim    switch(code) {
2420249259Sdim      case lir_log   : __ flog() ; break;
2421249259Sdim      case lir_log10 : __ flog10() ; break;
2422249259Sdim      case lir_abs   : __ fabs() ; break;
2423249259Sdim      case lir_sqrt  : __ fsqrt(); break;
2424249259Sdim      case lir_sin   :
2425249259Sdim        // Should consider not saving rbx, if not necessary
2426249259Sdim        __ trigfunc('s', op->as_Op2()->fpu_stack_size());
2427249259Sdim        break;
2428249259Sdim      case lir_cos :
2429249259Sdim        // Should consider not saving rbx, if not necessary
2430249259Sdim        assert(op->as_Op2()->fpu_stack_size() <= 6, "sin and cos need two free stack slots");
2431249259Sdim        __ trigfunc('c', op->as_Op2()->fpu_stack_size());
2432249259Sdim        break;
2433249259Sdim      case lir_tan :
2434249259Sdim        // Should consider not saving rbx, if not necessary
2435249259Sdim        __ trigfunc('t', op->as_Op2()->fpu_stack_size());
2436249259Sdim        break;
2437249259Sdim      default      : ShouldNotReachHere();
2438249259Sdim    }
2439249259Sdim  } else {
2440249259Sdim    Unimplemented();
2441249259Sdim  }
2442249259Sdim}
2443249259Sdim
2444249259Sdimvoid LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst) {
2445249259Sdim  // assert(left->destroys_register(), "check");
2446249259Sdim  if (left->is_single_cpu()) {
2447249259Sdim    Register reg = left->as_register();
2448249259Sdim    if (right->is_constant()) {
2449249259Sdim      int val = right->as_constant_ptr()->as_jint();
2450249259Sdim      switch (code) {
2451249259Sdim        case lir_logic_and: __ andl (reg, val); break;
2452249259Sdim        case lir_logic_or:  __ orl  (reg, val); break;
2453249259Sdim        case lir_logic_xor: __ xorl (reg, val); break;
2454249259Sdim        default: ShouldNotReachHere();
2455249259Sdim      }
2456249259Sdim    } else if (right->is_stack()) {
2457249259Sdim      // added support for stack operands
2458249259Sdim      Address raddr = frame_map()->address_for_slot(right->single_stack_ix());
2459249259Sdim      switch (code) {
2460249259Sdim        case lir_logic_and: __ andl (reg, raddr); break;
2461249259Sdim        case lir_logic_or:  __ orl  (reg, raddr); break;
2462249259Sdim        case lir_logic_xor: __ xorl (reg, raddr); break;
2463249259Sdim        default: ShouldNotReachHere();
2464249259Sdim      }
2465249259Sdim    } else {
2466249259Sdim      Register rright = right->as_register();
2467249259Sdim      switch (code) {
2468249259Sdim        case lir_logic_and: __ andptr (reg, rright); break;
2469249259Sdim        case lir_logic_or : __ orptr  (reg, rright); break;
2470249259Sdim        case lir_logic_xor: __ xorptr (reg, rright); break;
2471249259Sdim        default: ShouldNotReachHere();
2472249259Sdim      }
2473249259Sdim    }
2474249259Sdim    move_regs(reg, dst->as_register());
2475249259Sdim  } else {
2476249259Sdim    Register l_lo = left->as_register_lo();
2477249259Sdim    Register l_hi = left->as_register_hi();
2478249259Sdim    if (right->is_constant()) {
2479249259Sdim#ifdef _LP64
2480249259Sdim      __ mov64(rscratch1, right->as_constant_ptr()->as_jlong());
2481249259Sdim      switch (code) {
2482249259Sdim        case lir_logic_and:
2483249259Sdim          __ andq(l_lo, rscratch1);
2484249259Sdim          break;
2485249259Sdim        case lir_logic_or:
2486249259Sdim          __ orq(l_lo, rscratch1);
2487249259Sdim          break;
2488249259Sdim        case lir_logic_xor:
2489249259Sdim          __ xorq(l_lo, rscratch1);
2490249259Sdim          break;
2491249259Sdim        default: ShouldNotReachHere();
2492249259Sdim      }
2493249259Sdim#else
2494249259Sdim      int r_lo = right->as_constant_ptr()->as_jint_lo();
2495249259Sdim      int r_hi = right->as_constant_ptr()->as_jint_hi();
2496249259Sdim      switch (code) {
2497249259Sdim        case lir_logic_and:
2498249259Sdim          __ andl(l_lo, r_lo);
2499249259Sdim          __ andl(l_hi, r_hi);
2500249259Sdim          break;
2501249259Sdim        case lir_logic_or:
2502249259Sdim          __ orl(l_lo, r_lo);
2503249259Sdim          __ orl(l_hi, r_hi);
2504249259Sdim          break;
2505249259Sdim        case lir_logic_xor:
2506249259Sdim          __ xorl(l_lo, r_lo);
2507249259Sdim          __ xorl(l_hi, r_hi);
2508249259Sdim          break;
2509249259Sdim        default: ShouldNotReachHere();
2510249259Sdim      }
2511249259Sdim#endif // _LP64
2512249259Sdim    } else {
2513249259Sdim#ifdef _LP64
2514249259Sdim      Register r_lo;
2515249259Sdim      if (right->type() == T_OBJECT || right->type() == T_ARRAY) {
2516249259Sdim        r_lo = right->as_register();
2517249259Sdim      } else {
2518249259Sdim        r_lo = right->as_register_lo();
2519249259Sdim      }
2520249259Sdim#else
2521249259Sdim      Register r_lo = right->as_register_lo();
2522249259Sdim      Register r_hi = right->as_register_hi();
2523249259Sdim      assert(l_lo != r_hi, "overwriting registers");
2524249259Sdim#endif
2525249259Sdim      switch (code) {
2526249259Sdim        case lir_logic_and:
2527249259Sdim          __ andptr(l_lo, r_lo);
2528249259Sdim          NOT_LP64(__ andptr(l_hi, r_hi);)
2529249259Sdim          break;
2530249259Sdim        case lir_logic_or:
2531249259Sdim          __ orptr(l_lo, r_lo);
2532249259Sdim          NOT_LP64(__ orptr(l_hi, r_hi);)
2533249259Sdim          break;
2534249259Sdim        case lir_logic_xor:
2535249259Sdim          __ xorptr(l_lo, r_lo);
2536249259Sdim          NOT_LP64(__ xorptr(l_hi, r_hi);)
2537249259Sdim          break;
2538249259Sdim        default: ShouldNotReachHere();
2539249259Sdim      }
2540249259Sdim    }
2541249259Sdim
2542249259Sdim    Register dst_lo = dst->as_register_lo();
2543249259Sdim    Register dst_hi = dst->as_register_hi();
2544249259Sdim
2545249259Sdim#ifdef _LP64
2546249259Sdim    move_regs(l_lo, dst_lo);
2547249259Sdim#else
2548249259Sdim    if (dst_lo == l_hi) {
2549249259Sdim      assert(dst_hi != l_lo, "overwriting registers");
2550249259Sdim      move_regs(l_hi, dst_hi);
2551249259Sdim      move_regs(l_lo, dst_lo);
2552249259Sdim    } else {
2553249259Sdim      assert(dst_lo != l_hi, "overwriting registers");
2554249259Sdim      move_regs(l_lo, dst_lo);
2555249259Sdim      move_regs(l_hi, dst_hi);
2556249259Sdim    }
2557249259Sdim#endif // _LP64
2558249259Sdim  }
2559249259Sdim}
2560249259Sdim
2561249259Sdim
2562249259Sdim// we assume that rax, and rdx can be overwritten
2563249259Sdimvoid LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info) {
2564249259Sdim
2565249259Sdim  assert(left->is_single_cpu(),   "left must be register");
2566249259Sdim  assert(right->is_single_cpu() || right->is_constant(),  "right must be register or constant");
2567249259Sdim  assert(result->is_single_cpu(), "result must be register");
2568249259Sdim
2569249259Sdim  //  assert(left->destroys_register(), "check");
2570249259Sdim  //  assert(right->destroys_register(), "check");
2571249259Sdim
2572249259Sdim  Register lreg = left->as_register();
2573249259Sdim  Register dreg = result->as_register();
2574249259Sdim
2575249259Sdim  if (right->is_constant()) {
2576249259Sdim    int divisor = right->as_constant_ptr()->as_jint();
2577249259Sdim    assert(divisor > 0 && is_power_of_2(divisor), "must be");
2578249259Sdim    if (code == lir_idiv) {
2579249259Sdim      assert(lreg == rax, "must be rax,");
2580249259Sdim      assert(temp->as_register() == rdx, "tmp register must be rdx");
2581249259Sdim      __ cdql(); // sign extend into rdx:rax
2582249259Sdim      if (divisor == 2) {
2583249259Sdim        __ subl(lreg, rdx);
2584249259Sdim      } else {
2585249259Sdim        __ andl(rdx, divisor - 1);
2586249259Sdim        __ addl(lreg, rdx);
2587249259Sdim      }
2588249259Sdim      __ sarl(lreg, log2_intptr(divisor));
2589249259Sdim      move_regs(lreg, dreg);
2590249259Sdim    } else if (code == lir_irem) {
2591249259Sdim      Label done;
2592249259Sdim      __ mov(dreg, lreg);
2593249259Sdim      __ andl(dreg, 0x80000000 | (divisor - 1));
2594249259Sdim      __ jcc(Assembler::positive, done);
2595249259Sdim      __ decrement(dreg);
2596249259Sdim      __ orl(dreg, ~(divisor - 1));
2597249259Sdim      __ increment(dreg);
2598249259Sdim      __ bind(done);
2599249259Sdim    } else {
2600249259Sdim      ShouldNotReachHere();
2601249259Sdim    }
2602249259Sdim  } else {
2603249259Sdim    Register rreg = right->as_register();
2604249259Sdim    assert(lreg == rax, "left register must be rax,");
2605249259Sdim    assert(rreg != rdx, "right register must not be rdx");
2606249259Sdim    assert(temp->as_register() == rdx, "tmp register must be rdx");
2607249259Sdim
2608249259Sdim    move_regs(lreg, rax);
2609249259Sdim
2610249259Sdim    int idivl_offset = __ corrected_idivl(rreg);
2611249259Sdim    add_debug_info_for_div0(idivl_offset, info);
2612249259Sdim    if (code == lir_irem) {
2613249259Sdim      move_regs(rdx, dreg); // result is in rdx
2614249259Sdim    } else {
2615249259Sdim      move_regs(rax, dreg);
2616249259Sdim    }
2617249259Sdim  }
2618249259Sdim}
2619249259Sdim
2620249259Sdim
2621249259Sdimvoid LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Op2* op) {
2622249259Sdim  if (opr1->is_single_cpu()) {
2623249259Sdim    Register reg1 = opr1->as_register();
2624249259Sdim    if (opr2->is_single_cpu()) {
2625249259Sdim      // cpu register - cpu register
2626249259Sdim      if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) {
2627249259Sdim        __ cmpptr(reg1, opr2->as_register());
2628249259Sdim      } else {
2629249259Sdim        assert(opr2->type() != T_OBJECT && opr2->type() != T_ARRAY, "cmp int, oop?");
2630249259Sdim        __ cmpl(reg1, opr2->as_register());
2631249259Sdim      }
2632249259Sdim    } else if (opr2->is_stack()) {
2633249259Sdim      // cpu register - stack
2634249259Sdim      if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) {
2635249259Sdim        __ cmpptr(reg1, frame_map()->address_for_slot(opr2->single_stack_ix()));
2636249259Sdim      } else {
2637249259Sdim        __ cmpl(reg1, frame_map()->address_for_slot(opr2->single_stack_ix()));
2638249259Sdim      }
2639249259Sdim    } else if (opr2->is_constant()) {
2640249259Sdim      // cpu register - constant
2641249259Sdim      LIR_Const* c = opr2->as_constant_ptr();
2642249259Sdim      if (c->type() == T_INT) {
2643249259Sdim        __ cmpl(reg1, c->as_jint());
2644249259Sdim      } else if (c->type() == T_OBJECT || c->type() == T_ARRAY) {
2645249259Sdim        // In 64bit oops are single register
2646249259Sdim        jobject o = c->as_jobject();
2647249259Sdim        if (o == NULL) {
2648249259Sdim          __ cmpptr(reg1, (int32_t)NULL_WORD);
2649249259Sdim        } else {
2650249259Sdim#ifdef _LP64
2651249259Sdim          __ movoop(rscratch1, o);
2652249259Sdim          __ cmpptr(reg1, rscratch1);
2653249259Sdim#else
2654249259Sdim          __ cmpoop(reg1, c->as_jobject());
2655249259Sdim#endif // _LP64
2656249259Sdim        }
2657249259Sdim      } else {
2658249259Sdim        ShouldNotReachHere();
2659249259Sdim      }
2660249259Sdim      // cpu register - address
2661249259Sdim    } else if (opr2->is_address()) {
2662249259Sdim      if (op->info() != NULL) {
2663249259Sdim        add_debug_info_for_null_check_here(op->info());
2664249259Sdim      }
2665249259Sdim      __ cmpl(reg1, as_Address(opr2->as_address_ptr()));
2666249259Sdim    } else {
2667249259Sdim      ShouldNotReachHere();
2668249259Sdim    }
2669249259Sdim
2670249259Sdim  } else if(opr1->is_double_cpu()) {
2671249259Sdim    Register xlo = opr1->as_register_lo();
2672249259Sdim    Register xhi = opr1->as_register_hi();
2673249259Sdim    if (opr2->is_double_cpu()) {
2674249259Sdim#ifdef _LP64
2675249259Sdim      __ cmpptr(xlo, opr2->as_register_lo());
2676249259Sdim#else
2677249259Sdim      // cpu register - cpu register
2678249259Sdim      Register ylo = opr2->as_register_lo();
2679249259Sdim      Register yhi = opr2->as_register_hi();
2680249259Sdim      __ subl(xlo, ylo);
2681249259Sdim      __ sbbl(xhi, yhi);
2682249259Sdim      if (condition == lir_cond_equal || condition == lir_cond_notEqual) {
2683249259Sdim        __ orl(xhi, xlo);
2684249259Sdim      }
2685249259Sdim#endif // _LP64
2686249259Sdim    } else if (opr2->is_constant()) {
2687249259Sdim      // cpu register - constant 0
2688249259Sdim      assert(opr2->as_jlong() == (jlong)0, "only handles zero");
2689249259Sdim#ifdef _LP64
2690249259Sdim      __ cmpptr(xlo, (int32_t)opr2->as_jlong());
2691249259Sdim#else
2692249259Sdim      assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "only handles equals case");
2693249259Sdim      __ orl(xhi, xlo);
2694249259Sdim#endif // _LP64
2695249259Sdim    } else {
2696249259Sdim      ShouldNotReachHere();
2697249259Sdim    }
2698249259Sdim
2699249259Sdim  } else if (opr1->is_single_xmm()) {
2700249259Sdim    XMMRegister reg1 = opr1->as_xmm_float_reg();
2701249259Sdim    if (opr2->is_single_xmm()) {
2702249259Sdim      // xmm register - xmm register
2703249259Sdim      __ ucomiss(reg1, opr2->as_xmm_float_reg());
2704249259Sdim    } else if (opr2->is_stack()) {
2705249259Sdim      // xmm register - stack
2706249259Sdim      __ ucomiss(reg1, frame_map()->address_for_slot(opr2->single_stack_ix()));
2707249259Sdim    } else if (opr2->is_constant()) {
2708249259Sdim      // xmm register - constant
2709249259Sdim      __ ucomiss(reg1, InternalAddress(float_constant(opr2->as_jfloat())));
2710249259Sdim    } else if (opr2->is_address()) {
2711249259Sdim      // xmm register - address
2712249259Sdim      if (op->info() != NULL) {
2713249259Sdim        add_debug_info_for_null_check_here(op->info());
2714249259Sdim      }
2715249259Sdim      __ ucomiss(reg1, as_Address(opr2->as_address_ptr()));
2716249259Sdim    } else {
2717249259Sdim      ShouldNotReachHere();
2718249259Sdim    }
2719249259Sdim
2720249259Sdim  } else if (opr1->is_double_xmm()) {
2721249259Sdim    XMMRegister reg1 = opr1->as_xmm_double_reg();
2722249259Sdim    if (opr2->is_double_xmm()) {
2723249259Sdim      // xmm register - xmm register
2724249259Sdim      __ ucomisd(reg1, opr2->as_xmm_double_reg());
2725249259Sdim    } else if (opr2->is_stack()) {
2726249259Sdim      // xmm register - stack
2727249259Sdim      __ ucomisd(reg1, frame_map()->address_for_slot(opr2->double_stack_ix()));
2728249259Sdim    } else if (opr2->is_constant()) {
2729249259Sdim      // xmm register - constant
2730249259Sdim      __ ucomisd(reg1, InternalAddress(double_constant(opr2->as_jdouble())));
2731249259Sdim    } else if (opr2->is_address()) {
2732249259Sdim      // xmm register - address
2733249259Sdim      if (op->info() != NULL) {
2734249259Sdim        add_debug_info_for_null_check_here(op->info());
2735249259Sdim      }
2736249259Sdim      __ ucomisd(reg1, as_Address(opr2->pointer()->as_address()));
2737249259Sdim    } else {
2738249259Sdim      ShouldNotReachHere();
2739249259Sdim    }
2740249259Sdim
2741249259Sdim  } else if(opr1->is_single_fpu() || opr1->is_double_fpu()) {
2742249259Sdim    assert(opr1->is_fpu_register() && opr1->fpu() == 0, "currently left-hand side must be on TOS (relax this restriction)");
2743249259Sdim    assert(opr2->is_fpu_register(), "both must be registers");
2744249259Sdim    __ fcmp(noreg, opr2->fpu(), op->fpu_pop_count() > 0, op->fpu_pop_count() > 1);
2745249259Sdim
2746249259Sdim  } else if (opr1->is_address() && opr2->is_constant()) {
2747249259Sdim    LIR_Const* c = opr2->as_constant_ptr();
2748249259Sdim#ifdef _LP64
2749249259Sdim    if (c->type() == T_OBJECT || c->type() == T_ARRAY) {
2750249259Sdim      assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "need to reverse");
2751249259Sdim      __ movoop(rscratch1, c->as_jobject());
2752249259Sdim    }
2753249259Sdim#endif // LP64
2754249259Sdim    if (op->info() != NULL) {
2755249259Sdim      add_debug_info_for_null_check_here(op->info());
2756249259Sdim    }
2757249259Sdim    // special case: address - constant
2758249259Sdim    LIR_Address* addr = opr1->as_address_ptr();
2759249259Sdim    if (c->type() == T_INT) {
2760249259Sdim      __ cmpl(as_Address(addr), c->as_jint());
2761249259Sdim    } else if (c->type() == T_OBJECT || c->type() == T_ARRAY) {
2762249259Sdim#ifdef _LP64
2763249259Sdim      // %%% Make this explode if addr isn't reachable until we figure out a
2764249259Sdim      // better strategy by giving noreg as the temp for as_Address
2765249259Sdim      __ cmpptr(rscratch1, as_Address(addr, noreg));
2766249259Sdim#else
2767249259Sdim      __ cmpoop(as_Address(addr), c->as_jobject());
2768249259Sdim#endif // _LP64
2769249259Sdim    } else {
2770249259Sdim      ShouldNotReachHere();
2771249259Sdim    }
2772249259Sdim
2773249259Sdim  } else {
2774249259Sdim    ShouldNotReachHere();
2775249259Sdim  }
2776249259Sdim}
2777249259Sdim
2778249259Sdimvoid LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst, LIR_Op2* op) {
2779249259Sdim  if (code == lir_cmp_fd2i || code == lir_ucmp_fd2i) {
2780249259Sdim    if (left->is_single_xmm()) {
2781249259Sdim      assert(right->is_single_xmm(), "must match");
2782249259Sdim      __ cmpss2int(left->as_xmm_float_reg(), right->as_xmm_float_reg(), dst->as_register(), code == lir_ucmp_fd2i);
2783249259Sdim    } else if (left->is_double_xmm()) {
2784249259Sdim      assert(right->is_double_xmm(), "must match");
2785249259Sdim      __ cmpsd2int(left->as_xmm_double_reg(), right->as_xmm_double_reg(), dst->as_register(), code == lir_ucmp_fd2i);
2786249259Sdim
2787249259Sdim    } else {
2788249259Sdim      assert(left->is_single_fpu() || left->is_double_fpu(), "must be");
2789249259Sdim      assert(right->is_single_fpu() || right->is_double_fpu(), "must match");
2790249259Sdim
2791249259Sdim      assert(left->fpu() == 0, "left must be on TOS");
2792249259Sdim      __ fcmp2int(dst->as_register(), code == lir_ucmp_fd2i, right->fpu(),
2793249259Sdim                  op->fpu_pop_count() > 0, op->fpu_pop_count() > 1);
2794249259Sdim    }
2795249259Sdim  } else {
2796249259Sdim    assert(code == lir_cmp_l2i, "check");
2797249259Sdim#ifdef _LP64
2798249259Sdim    Label done;
2799249259Sdim    Register dest = dst->as_register();
2800249259Sdim    __ cmpptr(left->as_register_lo(), right->as_register_lo());
2801249259Sdim    __ movl(dest, -1);
2802249259Sdim    __ jccb(Assembler::less, done);
2803249259Sdim    __ set_byte_if_not_zero(dest);
2804249259Sdim    __ movzbl(dest, dest);
2805249259Sdim    __ bind(done);
2806249259Sdim#else
2807249259Sdim    __ lcmp2int(left->as_register_hi(),
2808249259Sdim                left->as_register_lo(),
2809249259Sdim                right->as_register_hi(),
2810249259Sdim                right->as_register_lo());
2811249259Sdim    move_regs(left->as_register_hi(), dst->as_register());
2812249259Sdim#endif // _LP64
2813249259Sdim  }
2814249259Sdim}
2815249259Sdim
2816249259Sdim
2817249259Sdimvoid LIR_Assembler::align_call(LIR_Code code) {
2818249259Sdim  if (os::is_MP()) {
2819249259Sdim    // make sure that the displacement word of the call ends up word aligned
2820249259Sdim    int offset = __ offset();
2821249259Sdim    switch (code) {
2822249259Sdim      case lir_static_call:
2823249259Sdim      case lir_optvirtual_call:
2824249259Sdim      case lir_dynamic_call:
2825249259Sdim        offset += NativeCall::displacement_offset;
2826        break;
2827      case lir_icvirtual_call:
2828        offset += NativeCall::displacement_offset + NativeMovConstReg::instruction_size;
2829      break;
2830      case lir_virtual_call:  // currently, sparc-specific for niagara
2831      default: ShouldNotReachHere();
2832    }
2833    while (offset++ % BytesPerWord != 0) {
2834      __ nop();
2835    }
2836  }
2837}
2838
2839
2840void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) {
2841  assert(!os::is_MP() || (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0,
2842         "must be aligned");
2843  __ call(AddressLiteral(op->addr(), rtype));
2844  add_call_info(code_offset(), op->info());
2845}
2846
2847
2848void LIR_Assembler::ic_call(LIR_OpJavaCall* op) {
2849  RelocationHolder rh = virtual_call_Relocation::spec(pc());
2850  __ movoop(IC_Klass, (jobject)Universe::non_oop_word());
2851  assert(!os::is_MP() ||
2852         (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0,
2853         "must be aligned");
2854  __ call(AddressLiteral(op->addr(), rh));
2855  add_call_info(code_offset(), op->info());
2856}
2857
2858
2859/* Currently, vtable-dispatch is only enabled for sparc platforms */
2860void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) {
2861  ShouldNotReachHere();
2862}
2863
2864
2865void LIR_Assembler::emit_static_call_stub() {
2866  address call_pc = __ pc();
2867  address stub = __ start_a_stub(call_stub_size);
2868  if (stub == NULL) {
2869    bailout("static call stub overflow");
2870    return;
2871  }
2872
2873  int start = __ offset();
2874  if (os::is_MP()) {
2875    // make sure that the displacement word of the call ends up word aligned
2876    int offset = __ offset() + NativeMovConstReg::instruction_size + NativeCall::displacement_offset;
2877    while (offset++ % BytesPerWord != 0) {
2878      __ nop();
2879    }
2880  }
2881  __ relocate(static_stub_Relocation::spec(call_pc));
2882  __ movoop(rbx, (jobject)NULL);
2883  // must be set to -1 at code generation time
2884  assert(!os::is_MP() || ((__ offset() + 1) % BytesPerWord) == 0, "must be aligned on MP");
2885  // On 64bit this will die since it will take a movq & jmp, must be only a jmp
2886  __ jump(RuntimeAddress(__ pc()));
2887
2888  assert(__ offset() - start <= call_stub_size, "stub too big");
2889  __ end_a_stub();
2890}
2891
2892
2893void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) {
2894  assert(exceptionOop->as_register() == rax, "must match");
2895  assert(exceptionPC->as_register() == rdx, "must match");
2896
2897  // exception object is not added to oop map by LinearScan
2898  // (LinearScan assumes that no oops are in fixed registers)
2899  info->add_register_oop(exceptionOop);
2900  Runtime1::StubID unwind_id;
2901
2902  // get current pc information
2903  // pc is only needed if the method has an exception handler, the unwind code does not need it.
2904  int pc_for_athrow_offset = __ offset();
2905  InternalAddress pc_for_athrow(__ pc());
2906  __ lea(exceptionPC->as_register(), pc_for_athrow);
2907  add_call_info(pc_for_athrow_offset, info); // for exception handler
2908
2909  __ verify_not_null_oop(rax);
2910  // search an exception handler (rax: exception oop, rdx: throwing pc)
2911  if (compilation()->has_fpu_code()) {
2912    unwind_id = Runtime1::handle_exception_id;
2913  } else {
2914    unwind_id = Runtime1::handle_exception_nofpu_id;
2915  }
2916  __ call(RuntimeAddress(Runtime1::entry_for(unwind_id)));
2917
2918  // enough room for two byte trap
2919  __ nop();
2920}
2921
2922
2923void LIR_Assembler::unwind_op(LIR_Opr exceptionOop) {
2924  assert(exceptionOop->as_register() == rax, "must match");
2925
2926  __ jmp(_unwind_handler_entry);
2927}
2928
2929
2930void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) {
2931
2932  // optimized version for linear scan:
2933  // * count must be already in ECX (guaranteed by LinearScan)
2934  // * left and dest must be equal
2935  // * tmp must be unused
2936  assert(count->as_register() == SHIFT_count, "count must be in ECX");
2937  assert(left == dest, "left and dest must be equal");
2938  assert(tmp->is_illegal(), "wasting a register if tmp is allocated");
2939
2940  if (left->is_single_cpu()) {
2941    Register value = left->as_register();
2942    assert(value != SHIFT_count, "left cannot be ECX");
2943
2944    switch (code) {
2945      case lir_shl:  __ shll(value); break;
2946      case lir_shr:  __ sarl(value); break;
2947      case lir_ushr: __ shrl(value); break;
2948      default: ShouldNotReachHere();
2949    }
2950  } else if (left->is_double_cpu()) {
2951    Register lo = left->as_register_lo();
2952    Register hi = left->as_register_hi();
2953    assert(lo != SHIFT_count && hi != SHIFT_count, "left cannot be ECX");
2954#ifdef _LP64
2955    switch (code) {
2956      case lir_shl:  __ shlptr(lo);        break;
2957      case lir_shr:  __ sarptr(lo);        break;
2958      case lir_ushr: __ shrptr(lo);        break;
2959      default: ShouldNotReachHere();
2960    }
2961#else
2962
2963    switch (code) {
2964      case lir_shl:  __ lshl(hi, lo);        break;
2965      case lir_shr:  __ lshr(hi, lo, true);  break;
2966      case lir_ushr: __ lshr(hi, lo, false); break;
2967      default: ShouldNotReachHere();
2968    }
2969#endif // LP64
2970  } else {
2971    ShouldNotReachHere();
2972  }
2973}
2974
2975
2976void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, jint count, LIR_Opr dest) {
2977  if (dest->is_single_cpu()) {
2978    // first move left into dest so that left is not destroyed by the shift
2979    Register value = dest->as_register();
2980    count = count & 0x1F; // Java spec
2981
2982    move_regs(left->as_register(), value);
2983    switch (code) {
2984      case lir_shl:  __ shll(value, count); break;
2985      case lir_shr:  __ sarl(value, count); break;
2986      case lir_ushr: __ shrl(value, count); break;
2987      default: ShouldNotReachHere();
2988    }
2989  } else if (dest->is_double_cpu()) {
2990#ifndef _LP64
2991    Unimplemented();
2992#else
2993    // first move left into dest so that left is not destroyed by the shift
2994    Register value = dest->as_register_lo();
2995    count = count & 0x1F; // Java spec
2996
2997    move_regs(left->as_register_lo(), value);
2998    switch (code) {
2999      case lir_shl:  __ shlptr(value, count); break;
3000      case lir_shr:  __ sarptr(value, count); break;
3001      case lir_ushr: __ shrptr(value, count); break;
3002      default: ShouldNotReachHere();
3003    }
3004#endif // _LP64
3005  } else {
3006    ShouldNotReachHere();
3007  }
3008}
3009
3010
3011void LIR_Assembler::store_parameter(Register r, int offset_from_rsp_in_words) {
3012  assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp");
3013  int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord;
3014  assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset");
3015  __ movptr (Address(rsp, offset_from_rsp_in_bytes), r);
3016}
3017
3018
3019void LIR_Assembler::store_parameter(jint c,     int offset_from_rsp_in_words) {
3020  assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp");
3021  int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord;
3022  assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset");
3023  __ movptr (Address(rsp, offset_from_rsp_in_bytes), c);
3024}
3025
3026
3027void LIR_Assembler::store_parameter(jobject o,  int offset_from_rsp_in_words) {
3028  assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp");
3029  int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord;
3030  assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset");
3031  __ movoop (Address(rsp, offset_from_rsp_in_bytes), o);
3032}
3033
3034
3035// This code replaces a call to arraycopy; no exception may
3036// be thrown in this code, they must be thrown in the System.arraycopy
3037// activation frame; we could save some checks if this would not be the case
3038void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
3039  ciArrayKlass* default_type = op->expected_type();
3040  Register src = op->src()->as_register();
3041  Register dst = op->dst()->as_register();
3042  Register src_pos = op->src_pos()->as_register();
3043  Register dst_pos = op->dst_pos()->as_register();
3044  Register length  = op->length()->as_register();
3045  Register tmp = op->tmp()->as_register();
3046
3047  CodeStub* stub = op->stub();
3048  int flags = op->flags();
3049  BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL;
3050  if (basic_type == T_ARRAY) basic_type = T_OBJECT;
3051
3052  // if we don't know anything, just go through the generic arraycopy
3053  if (default_type == NULL) {
3054    Label done;
3055    // save outgoing arguments on stack in case call to System.arraycopy is needed
3056    // HACK ALERT. This code used to push the parameters in a hardwired fashion
3057    // for interpreter calling conventions. Now we have to do it in new style conventions.
3058    // For the moment until C1 gets the new register allocator I just force all the
3059    // args to the right place (except the register args) and then on the back side
3060    // reload the register args properly if we go slow path. Yuck
3061
3062    // These are proper for the calling convention
3063    store_parameter(length, 2);
3064    store_parameter(dst_pos, 1);
3065    store_parameter(dst, 0);
3066
3067    // these are just temporary placements until we need to reload
3068    store_parameter(src_pos, 3);
3069    store_parameter(src, 4);
3070    NOT_LP64(assert(src == rcx && src_pos == rdx, "mismatch in calling convention");)
3071
3072    address C_entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy);
3073
3074    address copyfunc_addr = StubRoutines::generic_arraycopy();
3075
3076    // pass arguments: may push as this is not a safepoint; SP must be fix at each safepoint
3077#ifdef _LP64
3078    // The arguments are in java calling convention so we can trivially shift them to C
3079    // convention
3080    assert_different_registers(c_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4);
3081    __ mov(c_rarg0, j_rarg0);
3082    assert_different_registers(c_rarg1, j_rarg2, j_rarg3, j_rarg4);
3083    __ mov(c_rarg1, j_rarg1);
3084    assert_different_registers(c_rarg2, j_rarg3, j_rarg4);
3085    __ mov(c_rarg2, j_rarg2);
3086    assert_different_registers(c_rarg3, j_rarg4);
3087    __ mov(c_rarg3, j_rarg3);
3088#ifdef _WIN64
3089    // Allocate abi space for args but be sure to keep stack aligned
3090    __ subptr(rsp, 6*wordSize);
3091    store_parameter(j_rarg4, 4);
3092    if (copyfunc_addr == NULL) { // Use C version if stub was not generated
3093      __ call(RuntimeAddress(C_entry));
3094    } else {
3095#ifndef PRODUCT
3096      if (PrintC1Statistics) {
3097        __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));
3098      }
3099#endif
3100      __ call(RuntimeAddress(copyfunc_addr));
3101    }
3102    __ addptr(rsp, 6*wordSize);
3103#else
3104    __ mov(c_rarg4, j_rarg4);
3105    if (copyfunc_addr == NULL) { // Use C version if stub was not generated
3106      __ call(RuntimeAddress(C_entry));
3107    } else {
3108#ifndef PRODUCT
3109      if (PrintC1Statistics) {
3110        __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));
3111      }
3112#endif
3113      __ call(RuntimeAddress(copyfunc_addr));
3114    }
3115#endif // _WIN64
3116#else
3117    __ push(length);
3118    __ push(dst_pos);
3119    __ push(dst);
3120    __ push(src_pos);
3121    __ push(src);
3122
3123    if (copyfunc_addr == NULL) { // Use C version if stub was not generated
3124      __ call_VM_leaf(C_entry, 5); // removes pushed parameter from the stack
3125    } else {
3126#ifndef PRODUCT
3127      if (PrintC1Statistics) {
3128        __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));
3129      }
3130#endif
3131      __ call_VM_leaf(copyfunc_addr, 5); // removes pushed parameter from the stack
3132    }
3133
3134#endif // _LP64
3135
3136    __ cmpl(rax, 0);
3137    __ jcc(Assembler::equal, *stub->continuation());
3138
3139    if (copyfunc_addr != NULL) {
3140      __ mov(tmp, rax);
3141      __ xorl(tmp, -1);
3142    }
3143
3144    // Reload values from the stack so they are where the stub
3145    // expects them.
3146    __ movptr   (dst,     Address(rsp, 0*BytesPerWord));
3147    __ movptr   (dst_pos, Address(rsp, 1*BytesPerWord));
3148    __ movptr   (length,  Address(rsp, 2*BytesPerWord));
3149    __ movptr   (src_pos, Address(rsp, 3*BytesPerWord));
3150    __ movptr   (src,     Address(rsp, 4*BytesPerWord));
3151
3152    if (copyfunc_addr != NULL) {
3153      __ subl(length, tmp);
3154      __ addl(src_pos, tmp);
3155      __ addl(dst_pos, tmp);
3156    }
3157    __ jmp(*stub->entry());
3158
3159    __ bind(*stub->continuation());
3160    return;
3161  }
3162
3163  assert(default_type != NULL && default_type->is_array_klass() && default_type->is_loaded(), "must be true at this point");
3164
3165  int elem_size = type2aelembytes(basic_type);
3166  int shift_amount;
3167  Address::ScaleFactor scale;
3168
3169  switch (elem_size) {
3170    case 1 :
3171      shift_amount = 0;
3172      scale = Address::times_1;
3173      break;
3174    case 2 :
3175      shift_amount = 1;
3176      scale = Address::times_2;
3177      break;
3178    case 4 :
3179      shift_amount = 2;
3180      scale = Address::times_4;
3181      break;
3182    case 8 :
3183      shift_amount = 3;
3184      scale = Address::times_8;
3185      break;
3186    default:
3187      ShouldNotReachHere();
3188  }
3189
3190  Address src_length_addr = Address(src, arrayOopDesc::length_offset_in_bytes());
3191  Address dst_length_addr = Address(dst, arrayOopDesc::length_offset_in_bytes());
3192  Address src_klass_addr = Address(src, oopDesc::klass_offset_in_bytes());
3193  Address dst_klass_addr = Address(dst, oopDesc::klass_offset_in_bytes());
3194
3195  // length and pos's are all sign extended at this point on 64bit
3196
3197  // test for NULL
3198  if (flags & LIR_OpArrayCopy::src_null_check) {
3199    __ testptr(src, src);
3200    __ jcc(Assembler::zero, *stub->entry());
3201  }
3202  if (flags & LIR_OpArrayCopy::dst_null_check) {
3203    __ testptr(dst, dst);
3204    __ jcc(Assembler::zero, *stub->entry());
3205  }
3206
3207  // check if negative
3208  if (flags & LIR_OpArrayCopy::src_pos_positive_check) {
3209    __ testl(src_pos, src_pos);
3210    __ jcc(Assembler::less, *stub->entry());
3211  }
3212  if (flags & LIR_OpArrayCopy::dst_pos_positive_check) {
3213    __ testl(dst_pos, dst_pos);
3214    __ jcc(Assembler::less, *stub->entry());
3215  }
3216
3217  if (flags & LIR_OpArrayCopy::src_range_check) {
3218    __ lea(tmp, Address(src_pos, length, Address::times_1, 0));
3219    __ cmpl(tmp, src_length_addr);
3220    __ jcc(Assembler::above, *stub->entry());
3221  }
3222  if (flags & LIR_OpArrayCopy::dst_range_check) {
3223    __ lea(tmp, Address(dst_pos, length, Address::times_1, 0));
3224    __ cmpl(tmp, dst_length_addr);
3225    __ jcc(Assembler::above, *stub->entry());
3226  }
3227
3228  if (flags & LIR_OpArrayCopy::length_positive_check) {
3229    __ testl(length, length);
3230    __ jcc(Assembler::less, *stub->entry());
3231    __ jcc(Assembler::zero, *stub->continuation());
3232  }
3233
3234#ifdef _LP64
3235  __ movl2ptr(src_pos, src_pos); //higher 32bits must be null
3236  __ movl2ptr(dst_pos, dst_pos); //higher 32bits must be null
3237#endif
3238
3239  if (flags & LIR_OpArrayCopy::type_check) {
3240    // We don't know the array types are compatible
3241    if (basic_type != T_OBJECT) {
3242      // Simple test for basic type arrays
3243      if (UseCompressedOops) {
3244        __ movl(tmp, src_klass_addr);
3245        __ cmpl(tmp, dst_klass_addr);
3246      } else {
3247        __ movptr(tmp, src_klass_addr);
3248        __ cmpptr(tmp, dst_klass_addr);
3249      }
3250      __ jcc(Assembler::notEqual, *stub->entry());
3251    } else {
3252      // For object arrays, if src is a sub class of dst then we can
3253      // safely do the copy.
3254      Label cont, slow;
3255
3256      __ push(src);
3257      __ push(dst);
3258
3259      __ load_klass(src, src);
3260      __ load_klass(dst, dst);
3261
3262      __ check_klass_subtype_fast_path(src, dst, tmp, &cont, &slow, NULL);
3263
3264      __ push(src);
3265      __ push(dst);
3266      __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
3267      __ pop(dst);
3268      __ pop(src);
3269
3270      __ cmpl(src, 0);
3271      __ jcc(Assembler::notEqual, cont);
3272
3273      __ bind(slow);
3274      __ pop(dst);
3275      __ pop(src);
3276
3277      address copyfunc_addr = StubRoutines::checkcast_arraycopy();
3278      if (copyfunc_addr != NULL) { // use stub if available
3279        // src is not a sub class of dst so we have to do a
3280        // per-element check.
3281
3282        int mask = LIR_OpArrayCopy::src_objarray|LIR_OpArrayCopy::dst_objarray;
3283        if ((flags & mask) != mask) {
3284          // Check that at least both of them object arrays.
3285          assert(flags & mask, "one of the two should be known to be an object array");
3286
3287          if (!(flags & LIR_OpArrayCopy::src_objarray)) {
3288            __ load_klass(tmp, src);
3289          } else if (!(flags & LIR_OpArrayCopy::dst_objarray)) {
3290            __ load_klass(tmp, dst);
3291          }
3292          int lh_offset = klassOopDesc::header_size() * HeapWordSize +
3293            Klass::layout_helper_offset_in_bytes();
3294          Address klass_lh_addr(tmp, lh_offset);
3295          jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
3296          __ cmpl(klass_lh_addr, objArray_lh);
3297          __ jcc(Assembler::notEqual, *stub->entry());
3298        }
3299
3300       // Spill because stubs can use any register they like and it's
3301       // easier to restore just those that we care about.
3302       store_parameter(dst, 0);
3303       store_parameter(dst_pos, 1);
3304       store_parameter(length, 2);
3305       store_parameter(src_pos, 3);
3306       store_parameter(src, 4);
3307
3308#ifndef _LP64
3309        __ movptr(tmp, dst_klass_addr);
3310        __ movptr(tmp, Address(tmp, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)));
3311        __ push(tmp);
3312        __ movl(tmp, Address(tmp, Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc)));
3313        __ push(tmp);
3314        __ push(length);
3315        __ lea(tmp, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
3316        __ push(tmp);
3317        __ lea(tmp, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
3318        __ push(tmp);
3319
3320        __ call_VM_leaf(copyfunc_addr, 5);
3321#else
3322        __ movl2ptr(length, length); //higher 32bits must be null
3323
3324        __ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
3325        assert_different_registers(c_rarg0, dst, dst_pos, length);
3326        __ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
3327        assert_different_registers(c_rarg1, dst, length);
3328
3329        __ mov(c_rarg2, length);
3330        assert_different_registers(c_rarg2, dst);
3331
3332#ifdef _WIN64
3333        // Allocate abi space for args but be sure to keep stack aligned
3334        __ subptr(rsp, 6*wordSize);
3335        __ load_klass(c_rarg3, dst);
3336        __ movptr(c_rarg3, Address(c_rarg3, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)));
3337        store_parameter(c_rarg3, 4);
3338        __ movl(c_rarg3, Address(c_rarg3, Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc)));
3339        __ call(RuntimeAddress(copyfunc_addr));
3340        __ addptr(rsp, 6*wordSize);
3341#else
3342        __ load_klass(c_rarg4, dst);
3343        __ movptr(c_rarg4, Address(c_rarg4, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)));
3344        __ movl(c_rarg3, Address(c_rarg4, Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc)));
3345        __ call(RuntimeAddress(copyfunc_addr));
3346#endif
3347
3348#endif
3349
3350#ifndef PRODUCT
3351        if (PrintC1Statistics) {
3352          Label failed;
3353          __ testl(rax, rax);
3354          __ jcc(Assembler::notZero, failed);
3355          __ incrementl(ExternalAddress((address)&Runtime1::_arraycopy_checkcast_cnt));
3356          __ bind(failed);
3357        }
3358#endif
3359
3360        __ testl(rax, rax);
3361        __ jcc(Assembler::zero, *stub->continuation());
3362
3363#ifndef PRODUCT
3364        if (PrintC1Statistics) {
3365          __ incrementl(ExternalAddress((address)&Runtime1::_arraycopy_checkcast_attempt_cnt));
3366        }
3367#endif
3368
3369        __ mov(tmp, rax);
3370
3371        __ xorl(tmp, -1);
3372
3373        // Restore previously spilled arguments
3374        __ movptr   (dst,     Address(rsp, 0*BytesPerWord));
3375        __ movptr   (dst_pos, Address(rsp, 1*BytesPerWord));
3376        __ movptr   (length,  Address(rsp, 2*BytesPerWord));
3377        __ movptr   (src_pos, Address(rsp, 3*BytesPerWord));
3378        __ movptr   (src,     Address(rsp, 4*BytesPerWord));
3379
3380
3381        __ subl(length, tmp);
3382        __ addl(src_pos, tmp);
3383        __ addl(dst_pos, tmp);
3384      }
3385
3386      __ jmp(*stub->entry());
3387
3388      __ bind(cont);
3389      __ pop(dst);
3390      __ pop(src);
3391    }
3392  }
3393
3394#ifdef ASSERT
3395  if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) {
3396    // Sanity check the known type with the incoming class.  For the
3397    // primitive case the types must match exactly with src.klass and
3398    // dst.klass each exactly matching the default type.  For the
3399    // object array case, if no type check is needed then either the
3400    // dst type is exactly the expected type and the src type is a
3401    // subtype which we can't check or src is the same array as dst
3402    // but not necessarily exactly of type default_type.
3403    Label known_ok, halt;
3404    __ movoop(tmp, default_type->constant_encoding());
3405#ifdef _LP64
3406    if (UseCompressedOops) {
3407      __ encode_heap_oop(tmp);
3408    }
3409#endif
3410
3411    if (basic_type != T_OBJECT) {
3412
3413      if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr);
3414      else                   __ cmpptr(tmp, dst_klass_addr);
3415      __ jcc(Assembler::notEqual, halt);
3416      if (UseCompressedOops) __ cmpl(tmp, src_klass_addr);
3417      else                   __ cmpptr(tmp, src_klass_addr);
3418      __ jcc(Assembler::equal, known_ok);
3419    } else {
3420      if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr);
3421      else                   __ cmpptr(tmp, dst_klass_addr);
3422      __ jcc(Assembler::equal, known_ok);
3423      __ cmpptr(src, dst);
3424      __ jcc(Assembler::equal, known_ok);
3425    }
3426    __ bind(halt);
3427    __ stop("incorrect type information in arraycopy");
3428    __ bind(known_ok);
3429  }
3430#endif
3431
3432#ifndef PRODUCT
3433  if (PrintC1Statistics) {
3434    __ incrementl(ExternalAddress(Runtime1::arraycopy_count_address(basic_type)));
3435  }
3436#endif
3437
3438#ifdef _LP64
3439  assert_different_registers(c_rarg0, dst, dst_pos, length);
3440  __ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
3441  assert_different_registers(c_rarg1, length);
3442  __ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
3443  __ mov(c_rarg2, length);
3444
3445#else
3446  __ lea(tmp, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
3447  store_parameter(tmp, 0);
3448  __ lea(tmp, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));
3449  store_parameter(tmp, 1);
3450  store_parameter(length, 2);
3451#endif // _LP64
3452
3453  bool disjoint = (flags & LIR_OpArrayCopy::overlapping) == 0;
3454  bool aligned = (flags & LIR_OpArrayCopy::unaligned) == 0;
3455  const char *name;
3456  address entry = StubRoutines::select_arraycopy_function(basic_type, aligned, disjoint, name, false);
3457  __ call_VM_leaf(entry, 0);
3458
3459  __ bind(*stub->continuation());
3460}
3461
3462
3463void LIR_Assembler::emit_lock(LIR_OpLock* op) {
3464  Register obj = op->obj_opr()->as_register();  // may not be an oop
3465  Register hdr = op->hdr_opr()->as_register();
3466  Register lock = op->lock_opr()->as_register();
3467  if (!UseFastLocking) {
3468    __ jmp(*op->stub()->entry());
3469  } else if (op->code() == lir_lock) {
3470    Register scratch = noreg;
3471    if (UseBiasedLocking) {
3472      scratch = op->scratch_opr()->as_register();
3473    }
3474    assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
3475    // add debug info for NullPointerException only if one is possible
3476    int null_check_offset = __ lock_object(hdr, obj, lock, scratch, *op->stub()->entry());
3477    if (op->info() != NULL) {
3478      add_debug_info_for_null_check(null_check_offset, op->info());
3479    }
3480    // done
3481  } else if (op->code() == lir_unlock) {
3482    assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
3483    __ unlock_object(hdr, obj, lock, *op->stub()->entry());
3484  } else {
3485    Unimplemented();
3486  }
3487  __ bind(*op->stub()->continuation());
3488}
3489
3490
3491void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
3492  ciMethod* method = op->profiled_method();
3493  int bci          = op->profiled_bci();
3494
3495  // Update counter for all call types
3496  ciMethodData* md = method->method_data_or_null();
3497  assert(md != NULL, "Sanity");
3498  ciProfileData* data = md->bci_to_data(bci);
3499  assert(data->is_CounterData(), "need CounterData for calls");
3500  assert(op->mdo()->is_single_cpu(),  "mdo must be allocated");
3501  Register mdo  = op->mdo()->as_register();
3502  __ movoop(mdo, md->constant_encoding());
3503  Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
3504  Bytecodes::Code bc = method->java_code_at_bci(bci);
3505  // Perform additional virtual call profiling for invokevirtual and
3506  // invokeinterface bytecodes
3507  if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) &&
3508      C1ProfileVirtualCalls) {
3509    assert(op->recv()->is_single_cpu(), "recv must be allocated");
3510    Register recv = op->recv()->as_register();
3511    assert_different_registers(mdo, recv);
3512    assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls");
3513    ciKlass* known_klass = op->known_holder();
3514    if (C1OptimizeVirtualCallProfiling && known_klass != NULL) {
3515      // We know the type that will be seen at this call site; we can
3516      // statically update the methodDataOop rather than needing to do
3517      // dynamic tests on the receiver type
3518
3519      // NOTE: we should probably put a lock around this search to
3520      // avoid collisions by concurrent compilations
3521      ciVirtualCallData* vc_data = (ciVirtualCallData*) data;
3522      uint i;
3523      for (i = 0; i < VirtualCallData::row_limit(); i++) {
3524        ciKlass* receiver = vc_data->receiver(i);
3525        if (known_klass->equals(receiver)) {
3526          Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
3527          __ addptr(data_addr, DataLayout::counter_increment);
3528          return;
3529        }
3530      }
3531
3532      // Receiver type not found in profile data; select an empty slot
3533
3534      // Note that this is less efficient than it should be because it
3535      // always does a write to the receiver part of the
3536      // VirtualCallData rather than just the first time
3537      for (i = 0; i < VirtualCallData::row_limit(); i++) {
3538        ciKlass* receiver = vc_data->receiver(i);
3539        if (receiver == NULL) {
3540          Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)));
3541          __ movoop(recv_addr, known_klass->constant_encoding());
3542          Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
3543          __ addptr(data_addr, DataLayout::counter_increment);
3544          return;
3545        }
3546      }
3547    } else {
3548      __ load_klass(recv, recv);
3549      Label update_done;
3550      type_profile_helper(mdo, md, data, recv, &update_done);
3551      // Receiver did not match any saved receiver and there is no empty row for it.
3552      // Increment total counter to indicate polymorphic case.
3553      __ addptr(counter_addr, DataLayout::counter_increment);
3554
3555      __ bind(update_done);
3556    }
3557  } else {
3558    // Static call
3559    __ addptr(counter_addr, DataLayout::counter_increment);
3560  }
3561}
3562
3563void LIR_Assembler::emit_delay(LIR_OpDelay*) {
3564  Unimplemented();
3565}
3566
3567
3568void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) {
3569  __ lea(dst->as_register(), frame_map()->address_for_monitor_lock(monitor_no));
3570}
3571
3572
3573void LIR_Assembler::align_backward_branch_target() {
3574  __ align(BytesPerWord);
3575}
3576
3577
3578void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) {
3579  if (left->is_single_cpu()) {
3580    __ negl(left->as_register());
3581    move_regs(left->as_register(), dest->as_register());
3582
3583  } else if (left->is_double_cpu()) {
3584    Register lo = left->as_register_lo();
3585#ifdef _LP64
3586    Register dst = dest->as_register_lo();
3587    __ movptr(dst, lo);
3588    __ negptr(dst);
3589#else
3590    Register hi = left->as_register_hi();
3591    __ lneg(hi, lo);
3592    if (dest->as_register_lo() == hi) {
3593      assert(dest->as_register_hi() != lo, "destroying register");
3594      move_regs(hi, dest->as_register_hi());
3595      move_regs(lo, dest->as_register_lo());
3596    } else {
3597      move_regs(lo, dest->as_register_lo());
3598      move_regs(hi, dest->as_register_hi());
3599    }
3600#endif // _LP64
3601
3602  } else if (dest->is_single_xmm()) {
3603    if (left->as_xmm_float_reg() != dest->as_xmm_float_reg()) {
3604      __ movflt(dest->as_xmm_float_reg(), left->as_xmm_float_reg());
3605    }
3606    __ xorps(dest->as_xmm_float_reg(),
3607             ExternalAddress((address)float_signflip_pool));
3608
3609  } else if (dest->is_double_xmm()) {
3610    if (left->as_xmm_double_reg() != dest->as_xmm_double_reg()) {
3611      __ movdbl(dest->as_xmm_double_reg(), left->as_xmm_double_reg());
3612    }
3613    __ xorpd(dest->as_xmm_double_reg(),
3614             ExternalAddress((address)double_signflip_pool));
3615
3616  } else if (left->is_single_fpu() || left->is_double_fpu()) {
3617    assert(left->fpu() == 0, "arg must be on TOS");
3618    assert(dest->fpu() == 0, "dest must be TOS");
3619    __ fchs();
3620
3621  } else {
3622    ShouldNotReachHere();
3623  }
3624}
3625
3626
3627void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest) {
3628  assert(addr->is_address() && dest->is_register(), "check");
3629  Register reg;
3630  reg = dest->as_pointer_register();
3631  __ lea(reg, as_Address(addr->as_address_ptr()));
3632}
3633
3634
3635
3636void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info) {
3637  assert(!tmp->is_valid(), "don't need temporary");
3638  __ call(RuntimeAddress(dest));
3639  if (info != NULL) {
3640    add_call_info_here(info);
3641  }
3642}
3643
3644
3645void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) {
3646  assert(type == T_LONG, "only for volatile long fields");
3647
3648  if (info != NULL) {
3649    add_debug_info_for_null_check_here(info);
3650  }
3651
3652  if (src->is_double_xmm()) {
3653    if (dest->is_double_cpu()) {
3654#ifdef _LP64
3655      __ movdq(dest->as_register_lo(), src->as_xmm_double_reg());
3656#else
3657      __ movdl(dest->as_register_lo(), src->as_xmm_double_reg());
3658      __ psrlq(src->as_xmm_double_reg(), 32);
3659      __ movdl(dest->as_register_hi(), src->as_xmm_double_reg());
3660#endif // _LP64
3661    } else if (dest->is_double_stack()) {
3662      __ movdbl(frame_map()->address_for_slot(dest->double_stack_ix()), src->as_xmm_double_reg());
3663    } else if (dest->is_address()) {
3664      __ movdbl(as_Address(dest->as_address_ptr()), src->as_xmm_double_reg());
3665    } else {
3666      ShouldNotReachHere();
3667    }
3668
3669  } else if (dest->is_double_xmm()) {
3670    if (src->is_double_stack()) {
3671      __ movdbl(dest->as_xmm_double_reg(), frame_map()->address_for_slot(src->double_stack_ix()));
3672    } else if (src->is_address()) {
3673      __ movdbl(dest->as_xmm_double_reg(), as_Address(src->as_address_ptr()));
3674    } else {
3675      ShouldNotReachHere();
3676    }
3677
3678  } else if (src->is_double_fpu()) {
3679    assert(src->fpu_regnrLo() == 0, "must be TOS");
3680    if (dest->is_double_stack()) {
3681      __ fistp_d(frame_map()->address_for_slot(dest->double_stack_ix()));
3682    } else if (dest->is_address()) {
3683      __ fistp_d(as_Address(dest->as_address_ptr()));
3684    } else {
3685      ShouldNotReachHere();
3686    }
3687
3688  } else if (dest->is_double_fpu()) {
3689    assert(dest->fpu_regnrLo() == 0, "must be TOS");
3690    if (src->is_double_stack()) {
3691      __ fild_d(frame_map()->address_for_slot(src->double_stack_ix()));
3692    } else if (src->is_address()) {
3693      __ fild_d(as_Address(src->as_address_ptr()));
3694    } else {
3695      ShouldNotReachHere();
3696    }
3697  } else {
3698    ShouldNotReachHere();
3699  }
3700}
3701
3702
3703void LIR_Assembler::membar() {
3704  // QQQ sparc TSO uses this,
3705  __ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad));
3706}
3707
3708void LIR_Assembler::membar_acquire() {
3709  // No x86 machines currently require load fences
3710  // __ load_fence();
3711}
3712
3713void LIR_Assembler::membar_release() {
3714  // No x86 machines currently require store fences
3715  // __ store_fence();
3716}
3717
3718void LIR_Assembler::get_thread(LIR_Opr result_reg) {
3719  assert(result_reg->is_register(), "check");
3720#ifdef _LP64
3721  // __ get_thread(result_reg->as_register_lo());
3722  __ mov(result_reg->as_register(), r15_thread);
3723#else
3724  __ get_thread(result_reg->as_register());
3725#endif // _LP64
3726}
3727
3728
3729void LIR_Assembler::peephole(LIR_List*) {
3730  // do nothing for now
3731}
3732
3733
3734#undef __
3735