src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp
author chegar
Thu, 17 Oct 2019 20:54:25 +0100
branchdatagramsocketimpl-branch
changeset 58679 9c3209ff7550
parent 58678 9cf78a70fa4f
parent 58273 08a5148e7c4e
permissions -rw-r--r--
datagramsocketimpl-branch: merge with default
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
     1
/*
55398
e53ec3b362f4 8224851: AArch64: fix warnings and errors with Clang and GCC 8.3
ngasson
parents: 51963
diff changeset
     2
 * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
     3
 * Copyright (c) 2014, Red Hat Inc. All rights reserved.
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
     4
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
     5
 *
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
     6
 * This code is free software; you can redistribute it and/or modify it
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
     7
 * under the terms of the GNU General Public License version 2 only, as
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
     8
 * published by the Free Software Foundation.
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
     9
 *
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    10
 * This code is distributed in the hope that it will be useful, but WITHOUT
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    13
 * version 2 for more details (a copy is included in the LICENSE file that
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    14
 * accompanied this code).
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    15
 *
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    16
 * You should have received a copy of the GNU General Public License version
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    17
 * 2 along with this work; if not, write to the Free Software Foundation,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    18
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    19
 *
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    20
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    21
 * or visit www.oracle.com if you need additional information or have any
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    22
 * questions.
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    23
 *
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    24
 */
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    25
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    26
#include "precompiled.hpp"
50380
bec342339138 8204195: Clean up macroAssembler.inline.hpp and other inline.hpp files included in .hpp files
coleenp
parents: 50153
diff changeset
    27
#include "asm/macroAssembler.inline.hpp"
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    28
#include "c1/c1_Compilation.hpp"
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    29
#include "c1/c1_FrameMap.hpp"
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    30
#include "c1/c1_Instruction.hpp"
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    31
#include "c1/c1_LIRAssembler.hpp"
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    32
#include "c1/c1_LIRGenerator.hpp"
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    33
#include "c1/c1_Runtime1.hpp"
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    34
#include "c1/c1_ValueStack.hpp"
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    35
#include "ci/ciArray.hpp"
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    36
#include "ci/ciObjArrayKlass.hpp"
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    37
#include "ci/ciTypeArrayKlass.hpp"
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    38
#include "runtime/sharedRuntime.hpp"
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    39
#include "runtime/stubRoutines.hpp"
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    40
#include "vmreg_aarch64.inline.hpp"
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    41
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    42
#ifdef ASSERT
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    43
#define __ gen()->lir(__FILE__, __LINE__)->
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    44
#else
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    45
#define __ gen()->lir()->
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    46
#endif
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    47
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    48
// Item will be loaded into a byte register; Intel only
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    49
void LIRItem::load_byte_item() {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    50
  load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    51
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    52
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    53
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    54
void LIRItem::load_nonconstant() {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    55
  LIR_Opr r = value()->operand();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    56
  if (r->is_constant()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    57
    _result = r;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    58
  } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    59
    load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    60
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    61
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    62
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    63
//--------------------------------------------------------------
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    64
//               LIRGenerator
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    65
//--------------------------------------------------------------
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    66
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    67
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    68
LIR_Opr LIRGenerator::exceptionOopOpr() { return FrameMap::r0_oop_opr; }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    69
LIR_Opr LIRGenerator::exceptionPcOpr()  { return FrameMap::r3_opr; }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    70
LIR_Opr LIRGenerator::divInOpr()        { Unimplemented(); return LIR_OprFact::illegalOpr; }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    71
LIR_Opr LIRGenerator::divOutOpr()       { Unimplemented(); return LIR_OprFact::illegalOpr; }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    72
LIR_Opr LIRGenerator::remOutOpr()       { Unimplemented(); return LIR_OprFact::illegalOpr; }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    73
LIR_Opr LIRGenerator::shiftCountOpr()   { Unimplemented(); return LIR_OprFact::illegalOpr; }
34201
2de6f3566659 8138895: C1: PPC64 Port needs special register for Locks in synchronization code
mdoerr
parents: 29184
diff changeset
    74
LIR_Opr LIRGenerator::syncLockOpr()     { return new_register(T_INT); }
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    75
LIR_Opr LIRGenerator::syncTempOpr()     { return FrameMap::r0_opr; }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    76
LIR_Opr LIRGenerator::getThreadTemp()   { return LIR_OprFact::illegalOpr; }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    77
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    78
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    79
LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    80
  LIR_Opr opr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    81
  switch (type->tag()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    82
    case intTag:     opr = FrameMap::r0_opr;          break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    83
    case objectTag:  opr = FrameMap::r0_oop_opr;      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    84
    case longTag:    opr = FrameMap::long0_opr;        break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    85
    case floatTag:   opr = FrameMap::fpu0_float_opr;  break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    86
    case doubleTag:  opr = FrameMap::fpu0_double_opr;  break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    87
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    88
    case addressTag:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    89
    default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    90
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    91
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    92
  assert(opr->type_field() == as_OprType(as_BasicType(type)), "type mismatch");
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    93
  return opr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    94
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    95
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    96
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    97
LIR_Opr LIRGenerator::rlock_byte(BasicType type) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    98
  LIR_Opr reg = new_register(T_INT);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
    99
  set_vreg_flag(reg, LIRGenerator::byte_reg);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   100
  return reg;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   101
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   102
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   103
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   104
//--------- loading items into registers --------------------------------
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   105
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   106
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   107
bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   108
  if (v->type()->as_IntConstant() != NULL) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   109
    return v->type()->as_IntConstant()->value() == 0L;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   110
  } else if (v->type()->as_LongConstant() != NULL) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   111
    return v->type()->as_LongConstant()->value() == 0L;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   112
  } else if (v->type()->as_ObjectConstant() != NULL) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   113
    return v->type()->as_ObjectConstant()->value()->is_null_object();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   114
  } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   115
    return false;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   116
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   117
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   118
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   119
bool LIRGenerator::can_inline_as_constant(Value v) const {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   120
  // FIXME: Just a guess
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   121
  if (v->type()->as_IntConstant() != NULL) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   122
    return Assembler::operand_valid_for_add_sub_immediate(v->type()->as_IntConstant()->value());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   123
  } else if (v->type()->as_LongConstant() != NULL) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   124
    return v->type()->as_LongConstant()->value() == 0L;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   125
  } else if (v->type()->as_ObjectConstant() != NULL) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   126
    return v->type()->as_ObjectConstant()->value()->is_null_object();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   127
  } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   128
    return false;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   129
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   130
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   131
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   132
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   133
bool LIRGenerator::can_inline_as_constant(LIR_Const* c) const { return false; }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   134
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   135
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   136
LIR_Opr LIRGenerator::safepoint_poll_register() {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   137
  return LIR_OprFact::illegalOpr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   138
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   139
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   140
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   141
LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   142
                                            int shift, int disp, BasicType type) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   143
  assert(base->is_register(), "must be");
41337
4493ad6de04d 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
mdoerr
parents: 41323
diff changeset
   144
  intx large_disp = disp;
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   145
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   146
  // accumulate fixed displacements
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   147
  if (index->is_constant()) {
49906
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   148
    LIR_Const *constant = index->as_constant_ptr();
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   149
    if (constant->type() == T_INT) {
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   150
      large_disp += index->as_jint() << shift;
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   151
    } else {
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   152
      assert(constant->type() == T_LONG, "should be");
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   153
      jlong c = index->as_jlong() << shift;
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   154
      if ((jlong)((jint)c) == c) {
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   155
        large_disp += c;
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   156
        index = LIR_OprFact::illegalOpr;
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   157
      } else {
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   158
        LIR_Opr tmp = new_register(T_LONG);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   159
        __ move(index, tmp);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   160
        index = tmp;
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   161
        // apply shift and displacement below
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   162
      }
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   163
    }
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   164
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   165
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   166
  if (index->is_register()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   167
    // apply the shift and accumulate the displacement
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   168
    if (shift > 0) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   169
      LIR_Opr tmp = new_pointer_register();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   170
      __ shift_left(index, shift, tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   171
      index = tmp;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   172
    }
41337
4493ad6de04d 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
mdoerr
parents: 41323
diff changeset
   173
    if (large_disp != 0) {
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   174
      LIR_Opr tmp = new_pointer_register();
41337
4493ad6de04d 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
mdoerr
parents: 41323
diff changeset
   175
      if (Assembler::operand_valid_for_add_sub_immediate(large_disp)) {
4493ad6de04d 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
mdoerr
parents: 41323
diff changeset
   176
        __ add(tmp, tmp, LIR_OprFact::intptrConst(large_disp));
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   177
        index = tmp;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   178
      } else {
41337
4493ad6de04d 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
mdoerr
parents: 41323
diff changeset
   179
        __ move(tmp, LIR_OprFact::intptrConst(large_disp));
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   180
        __ add(tmp, index, tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   181
        index = tmp;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   182
      }
41337
4493ad6de04d 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
mdoerr
parents: 41323
diff changeset
   183
      large_disp = 0;
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   184
    }
41337
4493ad6de04d 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
mdoerr
parents: 41323
diff changeset
   185
  } else if (large_disp != 0 && !Address::offset_ok_for_immed(large_disp, shift)) {
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   186
    // index is illegal so replace it with the displacement loaded into a register
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   187
    index = new_pointer_register();
41337
4493ad6de04d 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
mdoerr
parents: 41323
diff changeset
   188
    __ move(LIR_OprFact::intptrConst(large_disp), index);
4493ad6de04d 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
mdoerr
parents: 41323
diff changeset
   189
    large_disp = 0;
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   190
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   191
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   192
  // at this point we either have base + index or base + displacement
41337
4493ad6de04d 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
mdoerr
parents: 41323
diff changeset
   193
  if (large_disp == 0) {
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   194
    return new LIR_Address(base, index, type);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   195
  } else {
41337
4493ad6de04d 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
mdoerr
parents: 41323
diff changeset
   196
    assert(Address::offset_ok_for_immed(large_disp, 0), "must be");
4493ad6de04d 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
mdoerr
parents: 41323
diff changeset
   197
    return new LIR_Address(base, large_disp, type);
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   198
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   199
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   200
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   201
LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr,
49906
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   202
                                              BasicType type) {
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   203
  int offset_in_bytes = arrayOopDesc::base_offset_in_bytes(type);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   204
  int elem_size = type2aelembytes(type);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   205
  int shift = exact_log2(elem_size);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   206
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   207
  LIR_Address* addr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   208
  if (index_opr->is_constant()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   209
    addr = new LIR_Address(array_opr,
41337
4493ad6de04d 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
mdoerr
parents: 41323
diff changeset
   210
                           offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type);
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   211
  } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   212
    if (offset_in_bytes) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   213
      LIR_Opr tmp = new_pointer_register();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   214
      __ add(array_opr, LIR_OprFact::intConst(offset_in_bytes), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   215
      array_opr = tmp;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   216
      offset_in_bytes = 0;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   217
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   218
    addr =  new LIR_Address(array_opr,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   219
                            index_opr,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   220
                            LIR_Address::scale(type),
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   221
                            offset_in_bytes, type);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   222
  }
49906
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   223
  return addr;
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   224
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   225
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   226
LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   227
  LIR_Opr r;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   228
  if (type == T_LONG) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   229
    r = LIR_OprFact::longConst(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   230
    if (!Assembler::operand_valid_for_logical_immediate(false, x)) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   231
      LIR_Opr tmp = new_register(type);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   232
      __ move(r, tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   233
      return tmp;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   234
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   235
  } else if (type == T_INT) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   236
    r = LIR_OprFact::intConst(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   237
    if (!Assembler::operand_valid_for_logical_immediate(true, x)) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   238
      // This is all rather nasty.  We don't know whether our constant
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   239
      // is required for a logical or an arithmetic operation, wo we
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   240
      // don't know what the range of valid values is!!
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   241
      LIR_Opr tmp = new_register(type);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   242
      __ move(r, tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   243
      return tmp;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   244
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   245
  } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   246
    ShouldNotReachHere();
35127
483603d4c7b2 8145553: Fix warnings in AArch64 directory
aph
parents: 34201
diff changeset
   247
    r = NULL;  // unreachable
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   248
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   249
  return r;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   250
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   251
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   252
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   253
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   254
void LIRGenerator::increment_counter(address counter, BasicType type, int step) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   255
  LIR_Opr pointer = new_pointer_register();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   256
  __ move(LIR_OprFact::intptrConst(counter), pointer);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   257
  LIR_Address* addr = new LIR_Address(pointer, type);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   258
  increment_counter(addr, step);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   259
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   260
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   261
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   262
void LIRGenerator::increment_counter(LIR_Address* addr, int step) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   263
  LIR_Opr imm = NULL;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   264
  switch(addr->type()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   265
  case T_INT:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   266
    imm = LIR_OprFact::intConst(step);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   267
    break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   268
  case T_LONG:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   269
    imm = LIR_OprFact::longConst(step);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   270
    break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   271
  default:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   272
    ShouldNotReachHere();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   273
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   274
  LIR_Opr reg = new_register(addr->type());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   275
  __ load(addr, reg);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   276
  __ add(reg, imm, reg);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   277
  __ store(reg, addr);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   278
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   279
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   280
void LIRGenerator::cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   281
  LIR_Opr reg = new_register(T_INT);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   282
  __ load(generate_address(base, disp, T_INT), reg, info);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   283
  __ cmp(condition, reg, LIR_OprFact::intConst(c));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   284
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   285
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   286
void LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, int disp, BasicType type, CodeEmitInfo* info) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   287
  LIR_Opr reg1 = new_register(T_INT);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   288
  __ load(generate_address(base, disp, type), reg1, info);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   289
  __ cmp(condition, reg, reg1);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   290
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   291
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   292
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   293
bool LIRGenerator::strength_reduce_multiply(LIR_Opr left, int c, LIR_Opr result, LIR_Opr tmp) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   294
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   295
  if (is_power_of_2(c - 1)) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   296
    __ shift_left(left, exact_log2(c - 1), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   297
    __ add(tmp, left, result);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   298
    return true;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   299
  } else if (is_power_of_2(c + 1)) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   300
    __ shift_left(left, exact_log2(c + 1), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   301
    __ sub(tmp, left, result);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   302
    return true;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   303
  } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   304
    return false;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   305
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   306
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   307
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   308
void LIRGenerator::store_stack_parameter (LIR_Opr item, ByteSize offset_from_sp) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   309
  BasicType type = item->type();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   310
  __ store(item, new LIR_Address(FrameMap::sp_opr, in_bytes(offset_from_sp), type));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   311
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   312
49906
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   313
void LIRGenerator::array_store_check(LIR_Opr value, LIR_Opr array, CodeEmitInfo* store_check_info, ciMethod* profiled_method, int profiled_bci) {
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   314
    LIR_Opr tmp1 = new_register(objectType);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   315
    LIR_Opr tmp2 = new_register(objectType);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   316
    LIR_Opr tmp3 = new_register(objectType);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   317
    __ store_check(value, array, tmp1, tmp2, tmp3, store_check_info, profiled_method, profiled_bci);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   318
}
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   319
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   320
//----------------------------------------------------------------------
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   321
//             visitor functions
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   322
//----------------------------------------------------------------------
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   323
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   324
void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   325
  assert(x->is_pinned(),"");
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   326
  LIRItem obj(x->obj(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   327
  obj.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   328
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   329
  set_no_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   330
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   331
  // "lock" stores the address of the monitor stack slot, so this is not an oop
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   332
  LIR_Opr lock = new_register(T_INT);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   333
  // Need a scratch register for biased locking
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   334
  LIR_Opr scratch = LIR_OprFact::illegalOpr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   335
  if (UseBiasedLocking) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   336
    scratch = new_register(T_INT);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   337
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   338
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   339
  CodeEmitInfo* info_for_exception = NULL;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   340
  if (x->needs_null_check()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   341
    info_for_exception = state_for(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   342
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   343
  // this CodeEmitInfo must not have the xhandlers because here the
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   344
  // object is already locked (xhandlers expect object to be unlocked)
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   345
  CodeEmitInfo* info = state_for(x, x->state(), true);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   346
  monitor_enter(obj.result(), lock, syncTempOpr(), scratch,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   347
                        x->monitor_no(), info_for_exception, info);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   348
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   349
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   350
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   351
void LIRGenerator::do_MonitorExit(MonitorExit* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   352
  assert(x->is_pinned(),"");
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   353
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   354
  LIRItem obj(x->obj(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   355
  obj.dont_load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   356
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   357
  LIR_Opr lock = new_register(T_INT);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   358
  LIR_Opr obj_temp = new_register(T_INT);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   359
  set_no_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   360
  monitor_exit(obj_temp, lock, syncTempOpr(), LIR_OprFact::illegalOpr, x->monitor_no());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   361
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   362
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   363
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   364
void LIRGenerator::do_NegateOp(NegateOp* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   365
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   366
  LIRItem from(x->x(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   367
  from.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   368
  LIR_Opr result = rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   369
  __ negate (from.result(), result);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   370
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   371
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   372
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   373
// for  _fadd, _fmul, _fsub, _fdiv, _frem
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   374
//      _dadd, _dmul, _dsub, _ddiv, _drem
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   375
void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   376
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   377
  if (x->op() == Bytecodes::_frem || x->op() == Bytecodes::_drem) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   378
    // float remainder is implemented as a direct call into the runtime
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   379
    LIRItem right(x->x(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   380
    LIRItem left(x->y(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   381
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   382
    BasicTypeList signature(2);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   383
    if (x->op() == Bytecodes::_frem) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   384
      signature.append(T_FLOAT);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   385
      signature.append(T_FLOAT);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   386
    } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   387
      signature.append(T_DOUBLE);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   388
      signature.append(T_DOUBLE);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   389
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   390
    CallingConvention* cc = frame_map()->c_calling_convention(&signature);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   391
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   392
    const LIR_Opr result_reg = result_register_for(x->type());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   393
    left.load_item_force(cc->at(1));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   394
    right.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   395
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   396
    __ move(right.result(), cc->at(0));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   397
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   398
    address entry;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   399
    if (x->op() == Bytecodes::_frem) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   400
      entry = CAST_FROM_FN_PTR(address, SharedRuntime::frem);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   401
    } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   402
      entry = CAST_FROM_FN_PTR(address, SharedRuntime::drem);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   403
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   404
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   405
    LIR_Opr result = rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   406
    __ call_runtime_leaf(entry, getThreadTemp(), result_reg, cc->args());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   407
    __ move(result_reg, result);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   408
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   409
    return;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   410
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   411
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   412
  LIRItem left(x->x(),  this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   413
  LIRItem right(x->y(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   414
  LIRItem* left_arg  = &left;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   415
  LIRItem* right_arg = &right;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   416
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   417
  // Always load right hand side.
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   418
  right.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   419
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   420
  if (!left.is_register())
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   421
    left.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   422
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   423
  LIR_Opr reg = rlock(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   424
  LIR_Opr tmp = LIR_OprFact::illegalOpr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   425
  if (x->is_strictfp() && (x->op() == Bytecodes::_dmul || x->op() == Bytecodes::_ddiv)) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   426
    tmp = new_register(T_DOUBLE);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   427
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   428
55398
e53ec3b362f4 8224851: AArch64: fix warnings and errors with Clang and GCC 8.3
ngasson
parents: 51963
diff changeset
   429
  arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), x->is_strictfp());
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   430
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   431
  set_result(x, round_item(reg));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   432
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   433
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   434
// for  _ladd, _lmul, _lsub, _ldiv, _lrem
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   435
void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   436
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   437
  // missing test if instr is commutative and if we should swap
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   438
  LIRItem left(x->x(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   439
  LIRItem right(x->y(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   440
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   441
  if (x->op() == Bytecodes::_ldiv || x->op() == Bytecodes::_lrem) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   442
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   443
    left.load_item();
51875
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   444
    bool need_zero_check = true;
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   445
    if (right.is_constant()) {
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   446
      jlong c = right.get_jlong_constant();
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   447
      // no need to do div-by-zero check if the divisor is a non-zero constant
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   448
      if (c != 0) need_zero_check = false;
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   449
      // do not load right if the divisor is a power-of-2 constant
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   450
      if (c > 0 && is_power_of_2_long(c)) {
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   451
        right.dont_load_item();
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   452
      } else {
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   453
        right.load_item();
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   454
      }
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   455
    } else {
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   456
      right.load_item();
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   457
    }
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   458
    if (need_zero_check) {
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   459
      CodeEmitInfo* info = state_for(x);
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   460
      __ cmp(lir_cond_equal, right.result(), LIR_OprFact::longConst(0));
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   461
      __ branch(lir_cond_equal, T_LONG, new DivByZeroStub(info));
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   462
    }
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   463
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   464
    rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   465
    switch (x->op()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   466
    case Bytecodes::_lrem:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   467
      __ rem (left.result(), right.result(), x->operand());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   468
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   469
    case Bytecodes::_ldiv:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   470
      __ div (left.result(), right.result(), x->operand());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   471
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   472
    default:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   473
      ShouldNotReachHere();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   474
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   475
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   476
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   477
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   478
  } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   479
    assert (x->op() == Bytecodes::_lmul || x->op() == Bytecodes::_ladd || x->op() == Bytecodes::_lsub,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   480
            "expect lmul, ladd or lsub");
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   481
    // add, sub, mul
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   482
    left.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   483
    if (! right.is_register()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   484
      if (x->op() == Bytecodes::_lmul
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   485
          || ! right.is_constant()
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   486
          || ! Assembler::operand_valid_for_add_sub_immediate(right.get_jlong_constant())) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   487
        right.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   488
      } else { // add, sub
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   489
        assert (x->op() == Bytecodes::_ladd || x->op() == Bytecodes::_lsub, "expect ladd or lsub");
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   490
        // don't load constants to save register
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   491
        right.load_nonconstant();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   492
      }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   493
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   494
    rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   495
    arithmetic_op_long(x->op(), x->operand(), left.result(), right.result(), NULL);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   496
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   497
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   498
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   499
// for: _iadd, _imul, _isub, _idiv, _irem
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   500
void LIRGenerator::do_ArithmeticOp_Int(ArithmeticOp* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   501
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   502
  // Test if instr is commutative and if we should swap
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   503
  LIRItem left(x->x(),  this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   504
  LIRItem right(x->y(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   505
  LIRItem* left_arg = &left;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   506
  LIRItem* right_arg = &right;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   507
  if (x->is_commutative() && left.is_stack() && right.is_register()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   508
    // swap them if left is real stack (or cached) and right is real register(not cached)
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   509
    left_arg = &right;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   510
    right_arg = &left;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   511
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   512
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   513
  left_arg->load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   514
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   515
  // do not need to load right, as we can handle stack and constants
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   516
  if (x->op() == Bytecodes::_idiv || x->op() == Bytecodes::_irem) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   517
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   518
    rlock_result(x);
51875
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   519
    bool need_zero_check = true;
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   520
    if (right.is_constant()) {
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   521
      jint c = right.get_jint_constant();
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   522
      // no need to do div-by-zero check if the divisor is a non-zero constant
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   523
      if (c != 0) need_zero_check = false;
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   524
      // do not load right if the divisor is a power-of-2 constant
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   525
      if (c > 0 && is_power_of_2(c)) {
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   526
        right_arg->dont_load_item();
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   527
      } else {
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   528
        right_arg->load_item();
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   529
      }
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   530
    } else {
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   531
      right_arg->load_item();
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   532
    }
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   533
    if (need_zero_check) {
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   534
      CodeEmitInfo* info = state_for(x);
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   535
      __ cmp(lir_cond_equal, right_arg->result(), LIR_OprFact::longConst(0));
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   536
      __ branch(lir_cond_equal, T_INT, new DivByZeroStub(info));
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   537
    }
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   538
51875
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   539
    LIR_Opr ill = LIR_OprFact::illegalOpr;
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   540
    if (x->op() == Bytecodes::_irem) {
51875
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   541
      __ irem(left_arg->result(), right_arg->result(), x->operand(), ill, NULL);
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   542
    } else if (x->op() == Bytecodes::_idiv) {
51875
e1368526699d 8210413: AArch64: Optimize div/rem by constant in C1
fyang
parents: 51487
diff changeset
   543
      __ idiv(left_arg->result(), right_arg->result(), x->operand(), ill, NULL);
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   544
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   545
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   546
  } else if (x->op() == Bytecodes::_iadd || x->op() == Bytecodes::_isub) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   547
    if (right.is_constant()
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   548
        && Assembler::operand_valid_for_add_sub_immediate(right.get_jint_constant())) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   549
      right.load_nonconstant();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   550
    } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   551
      right.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   552
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   553
    rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   554
    arithmetic_op_int(x->op(), x->operand(), left_arg->result(), right_arg->result(), LIR_OprFact::illegalOpr);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   555
  } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   556
    assert (x->op() == Bytecodes::_imul, "expect imul");
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   557
    if (right.is_constant()) {
45632
e56cfcaea55c 8181872: C1: possible overflow when strength reducing integer multiply by constant
vlivanov
parents: 45115
diff changeset
   558
      jint c = right.get_jint_constant();
e56cfcaea55c 8181872: C1: possible overflow when strength reducing integer multiply by constant
vlivanov
parents: 45115
diff changeset
   559
      if (c > 0 && c < max_jint && (is_power_of_2(c) || is_power_of_2(c - 1) || is_power_of_2(c + 1))) {
e56cfcaea55c 8181872: C1: possible overflow when strength reducing integer multiply by constant
vlivanov
parents: 45115
diff changeset
   560
        right_arg->dont_load_item();
e56cfcaea55c 8181872: C1: possible overflow when strength reducing integer multiply by constant
vlivanov
parents: 45115
diff changeset
   561
      } else {
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   562
        // Cannot use constant op.
45632
e56cfcaea55c 8181872: C1: possible overflow when strength reducing integer multiply by constant
vlivanov
parents: 45115
diff changeset
   563
        right_arg->load_item();
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   564
      }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   565
    } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   566
      right.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   567
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   568
    rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   569
    arithmetic_op_int(x->op(), x->operand(), left_arg->result(), right_arg->result(), new_register(T_INT));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   570
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   571
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   572
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   573
void LIRGenerator::do_ArithmeticOp(ArithmeticOp* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   574
  // when an operand with use count 1 is the left operand, then it is
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   575
  // likely that no move for 2-operand-LIR-form is necessary
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   576
  if (x->is_commutative() && x->y()->as_Constant() == NULL && x->x()->use_count() > x->y()->use_count()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   577
    x->swap_operands();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   578
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   579
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   580
  ValueTag tag = x->type()->tag();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   581
  assert(x->x()->type()->tag() == tag && x->y()->type()->tag() == tag, "wrong parameters");
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   582
  switch (tag) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   583
    case floatTag:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   584
    case doubleTag:  do_ArithmeticOp_FPU(x);  return;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   585
    case longTag:    do_ArithmeticOp_Long(x); return;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   586
    case intTag:     do_ArithmeticOp_Int(x);  return;
51963
8f0f7f2ae20b 8211170: AArch64: Warnings in C1 and template interpreter
aph
parents: 51875
diff changeset
   587
    default:         ShouldNotReachHere();    return;
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   588
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   589
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   590
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   591
// _ishl, _lshl, _ishr, _lshr, _iushr, _lushr
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   592
void LIRGenerator::do_ShiftOp(ShiftOp* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   593
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   594
  LIRItem left(x->x(),  this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   595
  LIRItem right(x->y(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   596
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   597
  left.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   598
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   599
  rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   600
  if (right.is_constant()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   601
    right.dont_load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   602
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   603
    switch (x->op()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   604
    case Bytecodes::_ishl: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   605
      int c = right.get_jint_constant() & 0x1f;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   606
      __ shift_left(left.result(), c, x->operand());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   607
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   608
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   609
    case Bytecodes::_ishr: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   610
      int c = right.get_jint_constant() & 0x1f;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   611
      __ shift_right(left.result(), c, x->operand());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   612
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   613
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   614
    case Bytecodes::_iushr: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   615
      int c = right.get_jint_constant() & 0x1f;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   616
      __ unsigned_shift_right(left.result(), c, x->operand());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   617
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   618
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   619
    case Bytecodes::_lshl: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   620
      int c = right.get_jint_constant() & 0x3f;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   621
      __ shift_left(left.result(), c, x->operand());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   622
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   623
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   624
    case Bytecodes::_lshr: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   625
      int c = right.get_jint_constant() & 0x3f;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   626
      __ shift_right(left.result(), c, x->operand());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   627
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   628
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   629
    case Bytecodes::_lushr: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   630
      int c = right.get_jint_constant() & 0x3f;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   631
      __ unsigned_shift_right(left.result(), c, x->operand());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   632
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   633
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   634
    default:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   635
      ShouldNotReachHere();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   636
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   637
  } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   638
    right.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   639
    LIR_Opr tmp = new_register(T_INT);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   640
    switch (x->op()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   641
    case Bytecodes::_ishl: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   642
      __ logical_and(right.result(), LIR_OprFact::intConst(0x1f), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   643
      __ shift_left(left.result(), tmp, x->operand(), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   644
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   645
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   646
    case Bytecodes::_ishr: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   647
      __ logical_and(right.result(), LIR_OprFact::intConst(0x1f), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   648
      __ shift_right(left.result(), tmp, x->operand(), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   649
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   650
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   651
    case Bytecodes::_iushr: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   652
      __ logical_and(right.result(), LIR_OprFact::intConst(0x1f), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   653
      __ unsigned_shift_right(left.result(), tmp, x->operand(), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   654
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   655
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   656
    case Bytecodes::_lshl: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   657
      __ logical_and(right.result(), LIR_OprFact::intConst(0x3f), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   658
      __ shift_left(left.result(), tmp, x->operand(), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   659
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   660
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   661
    case Bytecodes::_lshr: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   662
      __ logical_and(right.result(), LIR_OprFact::intConst(0x3f), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   663
      __ shift_right(left.result(), tmp, x->operand(), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   664
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   665
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   666
    case Bytecodes::_lushr: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   667
      __ logical_and(right.result(), LIR_OprFact::intConst(0x3f), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   668
      __ unsigned_shift_right(left.result(), tmp, x->operand(), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   669
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   670
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   671
    default:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   672
      ShouldNotReachHere();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   673
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   674
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   675
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   676
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   677
// _iand, _land, _ior, _lor, _ixor, _lxor
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   678
void LIRGenerator::do_LogicOp(LogicOp* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   679
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   680
  LIRItem left(x->x(),  this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   681
  LIRItem right(x->y(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   682
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   683
  left.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   684
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   685
  rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   686
  if (right.is_constant()
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   687
      && ((right.type()->tag() == intTag
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   688
           && Assembler::operand_valid_for_logical_immediate(true, right.get_jint_constant()))
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   689
          || (right.type()->tag() == longTag
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   690
              && Assembler::operand_valid_for_logical_immediate(false, right.get_jlong_constant()))))  {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   691
    right.dont_load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   692
  } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   693
    right.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   694
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   695
  switch (x->op()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   696
  case Bytecodes::_iand:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   697
  case Bytecodes::_land:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   698
    __ logical_and(left.result(), right.result(), x->operand()); break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   699
  case Bytecodes::_ior:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   700
  case Bytecodes::_lor:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   701
    __ logical_or (left.result(), right.result(), x->operand()); break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   702
  case Bytecodes::_ixor:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   703
  case Bytecodes::_lxor:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   704
    __ logical_xor(left.result(), right.result(), x->operand()); break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   705
  default: Unimplemented();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   706
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   707
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   708
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   709
// _lcmp, _fcmpl, _fcmpg, _dcmpl, _dcmpg
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   710
void LIRGenerator::do_CompareOp(CompareOp* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   711
  LIRItem left(x->x(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   712
  LIRItem right(x->y(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   713
  ValueTag tag = x->x()->type()->tag();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   714
  if (tag == longTag) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   715
    left.set_destroys_register();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   716
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   717
  left.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   718
  right.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   719
  LIR_Opr reg = rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   720
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   721
  if (x->x()->type()->is_float_kind()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   722
    Bytecodes::Code code = x->op();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   723
    __ fcmp2int(left.result(), right.result(), reg, (code == Bytecodes::_fcmpl || code == Bytecodes::_dcmpl));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   724
  } else if (x->x()->type()->tag() == longTag) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   725
    __ lcmp2int(left.result(), right.result(), reg);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   726
  } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   727
    Unimplemented();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   728
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   729
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   730
49906
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   731
LIR_Opr LIRGenerator::atomic_cmpxchg(BasicType type, LIR_Opr addr, LIRItem& cmp_value, LIRItem& new_value) {
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   732
  LIR_Opr ill = LIR_OprFact::illegalOpr;  // for convenience
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   733
  new_value.load_item();
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   734
  cmp_value.load_item();
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   735
  LIR_Opr result = new_register(T_INT);
58273
08a5148e7c4e 8230505: Replace JVM type comparisons to T_OBJECT and T_ARRAY with call to is_reference_type
lfoltan
parents: 55398
diff changeset
   736
  if (is_reference_type(type)) {
49906
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   737
    __ cas_obj(addr, cmp_value.result(), new_value.result(), new_register(T_INT), new_register(T_INT), result);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   738
  } else if (type == T_INT) {
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   739
    __ cas_int(addr->as_address_ptr()->base(), cmp_value.result(), new_value.result(), ill, ill);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   740
  } else if (type == T_LONG) {
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   741
    __ cas_long(addr->as_address_ptr()->base(), cmp_value.result(), new_value.result(), ill, ill);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   742
  } else {
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   743
    ShouldNotReachHere();
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   744
    Unimplemented();
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   745
  }
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   746
  __ logical_xor(FrameMap::r8_opr, LIR_OprFact::intConst(1), result);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   747
  return result;
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   748
}
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   749
49906
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   750
LIR_Opr LIRGenerator::atomic_xchg(BasicType type, LIR_Opr addr, LIRItem& value) {
58273
08a5148e7c4e 8230505: Replace JVM type comparisons to T_OBJECT and T_ARRAY with call to is_reference_type
lfoltan
parents: 55398
diff changeset
   751
  bool is_oop = is_reference_type(type);
49906
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   752
  LIR_Opr result = new_register(type);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   753
  value.load_item();
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   754
  assert(type == T_INT || is_oop LP64_ONLY( || type == T_LONG ), "unexpected type");
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   755
  LIR_Opr tmp = new_register(T_INT);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   756
  __ xchg(addr, value.result(), result, tmp);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   757
  return result;
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   758
}
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   759
49906
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   760
LIR_Opr LIRGenerator::atomic_add(BasicType type, LIR_Opr addr, LIRItem& value) {
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   761
  LIR_Opr result = new_register(type);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   762
  value.load_item();
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   763
  assert(type == T_INT LP64_ONLY( || type == T_LONG ), "unexpected type");
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   764
  LIR_Opr tmp = new_register(T_INT);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   765
  __ xadd(addr, value.result(), result, tmp);
4bb58f644e4e 8201543: Modularize C1 GC barriers
eosterlund
parents: 47767
diff changeset
   766
  return result;
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   767
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   768
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   769
void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
50755
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   770
  assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type");
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   771
  if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog ||
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   772
      x->id() == vmIntrinsics::_dpow || x->id() == vmIntrinsics::_dcos ||
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   773
      x->id() == vmIntrinsics::_dsin || x->id() == vmIntrinsics::_dtan ||
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   774
      x->id() == vmIntrinsics::_dlog10) {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   775
    do_LibmIntrinsic(x);
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   776
    return;
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   777
  }
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   778
  switch (x->id()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   779
    case vmIntrinsics::_dabs:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   780
    case vmIntrinsics::_dsqrt: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   781
      assert(x->number_of_arguments() == 1, "wrong type");
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   782
      LIRItem value(x->argument_at(0), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   783
      value.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   784
      LIR_Opr dst = rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   785
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   786
      switch (x->id()) {
50755
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   787
        case vmIntrinsics::_dsqrt: {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   788
          __ sqrt(value.result(), dst, LIR_OprFact::illegalOpr);
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   789
          break;
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   790
        }
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   791
        case vmIntrinsics::_dabs: {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   792
          __ abs(value.result(), dst, LIR_OprFact::illegalOpr);
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   793
          break;
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   794
        }
51963
8f0f7f2ae20b 8211170: AArch64: Warnings in C1 and template interpreter
aph
parents: 51875
diff changeset
   795
        default:
8f0f7f2ae20b 8211170: AArch64: Warnings in C1 and template interpreter
aph
parents: 51875
diff changeset
   796
          ShouldNotReachHere();
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   797
      }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   798
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   799
    }
51963
8f0f7f2ae20b 8211170: AArch64: Warnings in C1 and template interpreter
aph
parents: 51875
diff changeset
   800
    default:
8f0f7f2ae20b 8211170: AArch64: Warnings in C1 and template interpreter
aph
parents: 51875
diff changeset
   801
      ShouldNotReachHere();
50755
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   802
  }
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   803
}
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   804
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   805
void LIRGenerator::do_LibmIntrinsic(Intrinsic* x) {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   806
  LIRItem value(x->argument_at(0), this);
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   807
  value.set_destroys_register();
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   808
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   809
  LIR_Opr calc_result = rlock_result(x);
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   810
  LIR_Opr result_reg = result_register_for(x->type());
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   811
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   812
  CallingConvention* cc = NULL;
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   813
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   814
  if (x->id() == vmIntrinsics::_dpow) {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   815
    LIRItem value1(x->argument_at(1), this);
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   816
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   817
    value1.set_destroys_register();
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   818
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   819
    BasicTypeList signature(2);
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   820
    signature.append(T_DOUBLE);
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   821
    signature.append(T_DOUBLE);
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   822
    cc = frame_map()->c_calling_convention(&signature);
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   823
    value.load_item_force(cc->at(0));
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   824
    value1.load_item_force(cc->at(1));
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   825
  } else {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   826
    BasicTypeList signature(1);
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   827
    signature.append(T_DOUBLE);
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   828
    cc = frame_map()->c_calling_convention(&signature);
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   829
    value.load_item_force(cc->at(0));
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   830
  }
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   831
50755
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   832
  switch (x->id()) {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   833
    case vmIntrinsics::_dexp:
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   834
      if (StubRoutines::dexp() != NULL) {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   835
        __ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args());
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   836
      } else {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   837
        __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args());
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   838
      }
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   839
      break;
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   840
    case vmIntrinsics::_dlog:
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   841
      if (StubRoutines::dlog() != NULL) {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   842
        __ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args());
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   843
      } else {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   844
        __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args());
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   845
      }
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   846
      break;
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   847
    case vmIntrinsics::_dlog10:
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   848
      if (StubRoutines::dlog10() != NULL) {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   849
        __ call_runtime_leaf(StubRoutines::dlog10(), getThreadTemp(), result_reg, cc->args());
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   850
      } else {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   851
        __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10), getThreadTemp(), result_reg, cc->args());
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   852
      }
50755
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   853
      break;
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   854
    case vmIntrinsics::_dpow:
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   855
      if (StubRoutines::dpow() != NULL) {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   856
        __ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args());
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   857
      } else {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   858
        __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dpow), getThreadTemp(), result_reg, cc->args());
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   859
      }
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   860
      break;
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   861
    case vmIntrinsics::_dsin:
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   862
      if (StubRoutines::dsin() != NULL) {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   863
        __ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args());
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   864
      } else {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   865
        __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), getThreadTemp(), result_reg, cc->args());
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   866
      }
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   867
      break;
50755
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   868
    case vmIntrinsics::_dcos:
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   869
      if (StubRoutines::dcos() != NULL) {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   870
        __ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args());
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   871
      } else {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   872
        __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args());
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   873
      }
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   874
      break;
50755
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   875
    case vmIntrinsics::_dtan:
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   876
      if (StubRoutines::dtan() != NULL) {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   877
        __ call_runtime_leaf(StubRoutines::dtan(), getThreadTemp(), result_reg, cc->args());
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   878
      } else {
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   879
        __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), getThreadTemp(), result_reg, cc->args());
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   880
      }
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   881
      break;
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   882
    default:  ShouldNotReachHere();
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   883
  }
50755
680d04ae76e9 8204289: AARCH64: enable math intrinsics usage in interpreter and C1
dpochepk
parents: 50380
diff changeset
   884
  __ move(result_reg, calc_result);
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   885
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   886
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   887
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   888
void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   889
  assert(x->number_of_arguments() == 5, "wrong type");
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   890
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   891
  // Make all state_for calls early since they can emit code
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   892
  CodeEmitInfo* info = state_for(x, x->state());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   893
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   894
  LIRItem src(x->argument_at(0), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   895
  LIRItem src_pos(x->argument_at(1), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   896
  LIRItem dst(x->argument_at(2), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   897
  LIRItem dst_pos(x->argument_at(3), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   898
  LIRItem length(x->argument_at(4), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   899
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   900
  // operands for arraycopy must use fixed registers, otherwise
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   901
  // LinearScan will fail allocation (because arraycopy always needs a
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   902
  // call)
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   903
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   904
  // The java calling convention will give us enough registers
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   905
  // so that on the stub side the args will be perfect already.
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   906
  // On the other slow/special case side we call C and the arg
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   907
  // positions are not similar enough to pick one as the best.
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   908
  // Also because the java calling convention is a "shifted" version
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   909
  // of the C convention we can process the java args trivially into C
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   910
  // args without worry of overwriting during the xfer
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   911
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   912
  src.load_item_force     (FrameMap::as_oop_opr(j_rarg0));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   913
  src_pos.load_item_force (FrameMap::as_opr(j_rarg1));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   914
  dst.load_item_force     (FrameMap::as_oop_opr(j_rarg2));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   915
  dst_pos.load_item_force (FrameMap::as_opr(j_rarg3));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   916
  length.load_item_force  (FrameMap::as_opr(j_rarg4));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   917
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   918
  LIR_Opr tmp =           FrameMap::as_opr(j_rarg5);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   919
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   920
  set_no_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   921
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   922
  int flags;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   923
  ciArrayKlass* expected_type;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   924
  arraycopy_helper(x, &flags, &expected_type);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   925
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   926
  __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   927
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   928
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   929
void LIRGenerator::do_update_CRC32(Intrinsic* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   930
  assert(UseCRC32Intrinsics, "why are we here?");
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   931
  // Make all state_for calls early since they can emit code
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   932
  LIR_Opr result = rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   933
  int flags = 0;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   934
  switch (x->id()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   935
    case vmIntrinsics::_updateCRC32: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   936
      LIRItem crc(x->argument_at(0), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   937
      LIRItem val(x->argument_at(1), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   938
      // val is destroyed by update_crc32
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   939
      val.set_destroys_register();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   940
      crc.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   941
      val.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   942
      __ update_crc32(crc.result(), val.result(), result);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   943
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   944
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   945
    case vmIntrinsics::_updateBytesCRC32:
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   946
    case vmIntrinsics::_updateByteBufferCRC32: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   947
      bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   948
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   949
      LIRItem crc(x->argument_at(0), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   950
      LIRItem buf(x->argument_at(1), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   951
      LIRItem off(x->argument_at(2), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   952
      LIRItem len(x->argument_at(3), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   953
      buf.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   954
      off.load_nonconstant();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   955
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   956
      LIR_Opr index = off.result();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   957
      int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   958
      if(off.result()->is_constant()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   959
        index = LIR_OprFact::illegalOpr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   960
       offset += off.result()->as_jint();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   961
      }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   962
      LIR_Opr base_op = buf.result();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   963
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   964
      if (index->is_valid()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   965
        LIR_Opr tmp = new_register(T_LONG);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   966
        __ convert(Bytecodes::_i2l, index, tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   967
        index = tmp;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   968
      }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   969
51487
f791e6fb8040 8209667: Explicit barriers for C1/LIR
rkennke
parents: 50755
diff changeset
   970
      if (is_updateBytes) {
f791e6fb8040 8209667: Explicit barriers for C1/LIR
rkennke
parents: 50755
diff changeset
   971
        base_op = access_resolve(ACCESS_READ, base_op);
f791e6fb8040 8209667: Explicit barriers for C1/LIR
rkennke
parents: 50755
diff changeset
   972
      }
f791e6fb8040 8209667: Explicit barriers for C1/LIR
rkennke
parents: 50755
diff changeset
   973
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   974
      if (offset) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   975
        LIR_Opr tmp = new_pointer_register();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   976
        __ add(base_op, LIR_OprFact::intConst(offset), tmp);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   977
        base_op = tmp;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   978
        offset = 0;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   979
      }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   980
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   981
      LIR_Address* a = new LIR_Address(base_op,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   982
                                       index,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   983
                                       offset,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   984
                                       T_BYTE);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   985
      BasicTypeList signature(3);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   986
      signature.append(T_INT);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   987
      signature.append(T_ADDRESS);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   988
      signature.append(T_INT);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   989
      CallingConvention* cc = frame_map()->c_calling_convention(&signature);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   990
      const LIR_Opr result_reg = result_register_for(x->type());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   991
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   992
      LIR_Opr addr = new_pointer_register();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   993
      __ leal(LIR_OprFact::address(a), addr);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   994
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   995
      crc.load_item_force(cc->at(0));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   996
      __ move(addr, cc->at(1));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   997
      len.load_item_force(cc->at(2));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   998
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
   999
      __ call_runtime_leaf(StubRoutines::updateBytesCRC32(), getThreadTemp(), result_reg, cc->args());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1000
      __ move(result_reg, result);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1001
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1002
      break;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1003
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1004
    default: {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1005
      ShouldNotReachHere();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1006
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1007
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1008
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1009
38237
d972e3a2df53 8155162: java.util.zip.CRC32C Interpreter/C1 intrinsics support on SPARC
kvn
parents: 38031
diff changeset
  1010
void LIRGenerator::do_update_CRC32C(Intrinsic* x) {
47767
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1011
  assert(UseCRC32CIntrinsics, "why are we here?");
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1012
  // Make all state_for calls early since they can emit code
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1013
  LIR_Opr result = rlock_result(x);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1014
  int flags = 0;
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1015
  switch (x->id()) {
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1016
    case vmIntrinsics::_updateBytesCRC32C:
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1017
    case vmIntrinsics::_updateDirectByteBufferCRC32C: {
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1018
      bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32C);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1019
      int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0;
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1020
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1021
      LIRItem crc(x->argument_at(0), this);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1022
      LIRItem buf(x->argument_at(1), this);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1023
      LIRItem off(x->argument_at(2), this);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1024
      LIRItem end(x->argument_at(3), this);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1025
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1026
      buf.load_item();
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1027
      off.load_nonconstant();
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1028
      end.load_nonconstant();
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1029
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1030
      // len = end - off
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1031
      LIR_Opr len  = end.result();
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1032
      LIR_Opr tmpA = new_register(T_INT);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1033
      LIR_Opr tmpB = new_register(T_INT);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1034
      __ move(end.result(), tmpA);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1035
      __ move(off.result(), tmpB);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1036
      __ sub(tmpA, tmpB, tmpA);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1037
      len = tmpA;
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1038
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1039
      LIR_Opr index = off.result();
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1040
      if(off.result()->is_constant()) {
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1041
        index = LIR_OprFact::illegalOpr;
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1042
        offset += off.result()->as_jint();
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1043
      }
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1044
      LIR_Opr base_op = buf.result();
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1045
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1046
      if (index->is_valid()) {
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1047
        LIR_Opr tmp = new_register(T_LONG);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1048
        __ convert(Bytecodes::_i2l, index, tmp);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1049
        index = tmp;
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1050
      }
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1051
51487
f791e6fb8040 8209667: Explicit barriers for C1/LIR
rkennke
parents: 50755
diff changeset
  1052
      if (is_updateBytes) {
f791e6fb8040 8209667: Explicit barriers for C1/LIR
rkennke
parents: 50755
diff changeset
  1053
        base_op = access_resolve(ACCESS_READ, base_op);
f791e6fb8040 8209667: Explicit barriers for C1/LIR
rkennke
parents: 50755
diff changeset
  1054
      }
f791e6fb8040 8209667: Explicit barriers for C1/LIR
rkennke
parents: 50755
diff changeset
  1055
47767
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1056
      if (offset) {
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1057
        LIR_Opr tmp = new_pointer_register();
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1058
        __ add(base_op, LIR_OprFact::intConst(offset), tmp);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1059
        base_op = tmp;
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1060
        offset = 0;
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1061
      }
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1062
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1063
      LIR_Address* a = new LIR_Address(base_op,
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1064
                                       index,
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1065
                                       offset,
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1066
                                       T_BYTE);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1067
      BasicTypeList signature(3);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1068
      signature.append(T_INT);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1069
      signature.append(T_ADDRESS);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1070
      signature.append(T_INT);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1071
      CallingConvention* cc = frame_map()->c_calling_convention(&signature);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1072
      const LIR_Opr result_reg = result_register_for(x->type());
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1073
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1074
      LIR_Opr addr = new_pointer_register();
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1075
      __ leal(LIR_OprFact::address(a), addr);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1076
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1077
      crc.load_item_force(cc->at(0));
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1078
      __ move(addr, cc->at(1));
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1079
      __ move(len, cc->at(2));
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1080
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1081
      __ call_runtime_leaf(StubRoutines::updateBytesCRC32C(), getThreadTemp(), result_reg, cc->args());
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1082
      __ move(result_reg, result);
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1083
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1084
      break;
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1085
    }
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1086
    default: {
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1087
      ShouldNotReachHere();
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1088
    }
107622f2695c 8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
dchuyko
parents: 47216
diff changeset
  1089
  }
38237
d972e3a2df53 8155162: java.util.zip.CRC32C Interpreter/C1 intrinsics support on SPARC
kvn
parents: 38031
diff changeset
  1090
}
d972e3a2df53 8155162: java.util.zip.CRC32C Interpreter/C1 intrinsics support on SPARC
kvn
parents: 38031
diff changeset
  1091
41323
ddd5600d4762 8154122: Intrinsify fused mac operations
vdeshpande
parents: 40071
diff changeset
  1092
void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {
42653
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1093
  assert(x->number_of_arguments() == 3, "wrong type");
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1094
  assert(UseFMA, "Needs FMA instructions support.");
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1095
  LIRItem value(x->argument_at(0), this);
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1096
  LIRItem value1(x->argument_at(1), this);
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1097
  LIRItem value2(x->argument_at(2), this);
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1098
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1099
  value.load_item();
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1100
  value1.load_item();
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1101
  value2.load_item();
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1102
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1103
  LIR_Opr calc_input = value.result();
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1104
  LIR_Opr calc_input1 = value1.result();
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1105
  LIR_Opr calc_input2 = value2.result();
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1106
  LIR_Opr calc_result = rlock_result(x);
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1107
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1108
  switch (x->id()) {
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1109
  case vmIntrinsics::_fmaD:   __ fmad(calc_input, calc_input1, calc_input2, calc_result); break;
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1110
  case vmIntrinsics::_fmaF:   __ fmaf(calc_input, calc_input1, calc_input2, calc_result); break;
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1111
  default:                    ShouldNotReachHere();
62a5d76872d4 8162338: AArch64: Intrinsify fused mac operations
roland
parents: 41337
diff changeset
  1112
  }
41323
ddd5600d4762 8154122: Intrinsify fused mac operations
vdeshpande
parents: 40071
diff changeset
  1113
}
ddd5600d4762 8154122: Intrinsify fused mac operations
vdeshpande
parents: 40071
diff changeset
  1114
38238
1bbcc430c78d 8151268: Wire up the x86 _vectorizedMismatch stub routine in C1
psandoz
parents: 38237
diff changeset
  1115
void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {
1bbcc430c78d 8151268: Wire up the x86 _vectorizedMismatch stub routine in C1
psandoz
parents: 38237
diff changeset
  1116
  fatal("vectorizedMismatch intrinsic is not implemented on this platform");
1bbcc430c78d 8151268: Wire up the x86 _vectorizedMismatch stub routine in C1
psandoz
parents: 38237
diff changeset
  1117
}
1bbcc430c78d 8151268: Wire up the x86 _vectorizedMismatch stub routine in C1
psandoz
parents: 38237
diff changeset
  1118
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1119
// _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1120
// _i2b, _i2c, _i2s
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1121
void LIRGenerator::do_Convert(Convert* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1122
  LIRItem value(x->value(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1123
  value.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1124
  LIR_Opr input = value.result();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1125
  LIR_Opr result = rlock(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1126
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1127
  // arguments of lir_convert
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1128
  LIR_Opr conv_input = input;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1129
  LIR_Opr conv_result = result;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1130
  ConversionStub* stub = NULL;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1131
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1132
  __ convert(x->op(), conv_input, conv_result);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1133
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1134
  assert(result->is_virtual(), "result must be virtual register");
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1135
  set_result(x, result);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1136
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1137
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1138
void LIRGenerator::do_NewInstance(NewInstance* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1139
#ifndef PRODUCT
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1140
  if (PrintNotLoaded && !x->klass()->is_loaded()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1141
    tty->print_cr("   ###class not loaded at new bci %d", x->printable_bci());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1142
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1143
#endif
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1144
  CodeEmitInfo* info = state_for(x, x->state());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1145
  LIR_Opr reg = result_register_for(x->type());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1146
  new_instance(reg, x->klass(), x->is_unresolved(),
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1147
                       FrameMap::r2_oop_opr,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1148
                       FrameMap::r5_oop_opr,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1149
                       FrameMap::r4_oop_opr,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1150
                       LIR_OprFact::illegalOpr,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1151
                       FrameMap::r3_metadata_opr, info);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1152
  LIR_Opr result = rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1153
  __ move(reg, result);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1154
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1155
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1156
void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1157
  CodeEmitInfo* info = state_for(x, x->state());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1158
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1159
  LIRItem length(x->length(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1160
  length.load_item_force(FrameMap::r19_opr);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1161
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1162
  LIR_Opr reg = result_register_for(x->type());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1163
  LIR_Opr tmp1 = FrameMap::r2_oop_opr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1164
  LIR_Opr tmp2 = FrameMap::r4_oop_opr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1165
  LIR_Opr tmp3 = FrameMap::r5_oop_opr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1166
  LIR_Opr tmp4 = reg;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1167
  LIR_Opr klass_reg = FrameMap::r3_metadata_opr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1168
  LIR_Opr len = length.result();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1169
  BasicType elem_type = x->elt_type();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1170
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1171
  __ metadata2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1172
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1173
  CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1174
  __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1175
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1176
  LIR_Opr result = rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1177
  __ move(reg, result);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1178
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1179
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1180
void LIRGenerator::do_NewObjectArray(NewObjectArray* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1181
  LIRItem length(x->length(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1182
  // in case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1183
  // and therefore provide the state before the parameters have been consumed
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1184
  CodeEmitInfo* patching_info = NULL;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1185
  if (!x->klass()->is_loaded() || PatchALot) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1186
    patching_info =  state_for(x, x->state_before());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1187
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1188
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1189
  CodeEmitInfo* info = state_for(x, x->state());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1190
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1191
  LIR_Opr reg = result_register_for(x->type());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1192
  LIR_Opr tmp1 = FrameMap::r2_oop_opr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1193
  LIR_Opr tmp2 = FrameMap::r4_oop_opr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1194
  LIR_Opr tmp3 = FrameMap::r5_oop_opr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1195
  LIR_Opr tmp4 = reg;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1196
  LIR_Opr klass_reg = FrameMap::r3_metadata_opr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1197
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1198
  length.load_item_force(FrameMap::r19_opr);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1199
  LIR_Opr len = length.result();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1200
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1201
  CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1202
  ciKlass* obj = (ciKlass*) ciObjArrayKlass::make(x->klass());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1203
  if (obj == ciEnv::unloaded_ciobjarrayklass()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1204
    BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error");
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1205
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1206
  klass2reg_with_patching(klass_reg, obj, patching_info);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1207
  __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1208
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1209
  LIR_Opr result = rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1210
  __ move(reg, result);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1211
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1212
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1213
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1214
void LIRGenerator::do_NewMultiArray(NewMultiArray* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1215
  Values* dims = x->dims();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1216
  int i = dims->length();
38031
e0b822facc03 8149374: Replace C1-specific collection classes with universal collection classes
fzhinkin
parents: 35127
diff changeset
  1217
  LIRItemList* items = new LIRItemList(i, i, NULL);
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1218
  while (i-- > 0) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1219
    LIRItem* size = new LIRItem(dims->at(i), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1220
    items->at_put(i, size);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1221
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1222
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1223
  // Evaluate state_for early since it may emit code.
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1224
  CodeEmitInfo* patching_info = NULL;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1225
  if (!x->klass()->is_loaded() || PatchALot) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1226
    patching_info = state_for(x, x->state_before());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1227
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1228
    // Cannot re-use same xhandlers for multiple CodeEmitInfos, so
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1229
    // clone all handlers (NOTE: Usually this is handled transparently
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1230
    // by the CodeEmitInfo cloning logic in CodeStub constructors but
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1231
    // is done explicitly here because a stub isn't being used).
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1232
    x->set_exception_handlers(new XHandlers(x->exception_handlers()));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1233
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1234
  CodeEmitInfo* info = state_for(x, x->state());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1235
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1236
  i = dims->length();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1237
  while (i-- > 0) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1238
    LIRItem* size = items->at(i);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1239
    size->load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1240
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1241
    store_stack_parameter(size->result(), in_ByteSize(i*4));
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1242
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1243
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1244
  LIR_Opr klass_reg = FrameMap::r0_metadata_opr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1245
  klass2reg_with_patching(klass_reg, x->klass(), patching_info);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1246
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1247
  LIR_Opr rank = FrameMap::r19_opr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1248
  __ move(LIR_OprFact::intConst(x->rank()), rank);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1249
  LIR_Opr varargs = FrameMap::r2_opr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1250
  __ move(FrameMap::sp_opr, varargs);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1251
  LIR_OprList* args = new LIR_OprList(3);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1252
  args->append(klass_reg);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1253
  args->append(rank);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1254
  args->append(varargs);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1255
  LIR_Opr reg = result_register_for(x->type());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1256
  __ call_runtime(Runtime1::entry_for(Runtime1::new_multi_array_id),
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1257
                  LIR_OprFact::illegalOpr,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1258
                  reg, args, info);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1259
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1260
  LIR_Opr result = rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1261
  __ move(reg, result);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1262
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1263
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1264
void LIRGenerator::do_BlockBegin(BlockBegin* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1265
  // nothing to do for now
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1266
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1267
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1268
void LIRGenerator::do_CheckCast(CheckCast* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1269
  LIRItem obj(x->obj(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1270
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1271
  CodeEmitInfo* patching_info = NULL;
49933
c63bdf53a1a7 8202399: [C1] LIRGenerator::do_CheckCast needs to exclude is_invokespecial_receiver_check() when using PatchAlot
dholmes
parents: 49906
diff changeset
  1272
  if (!x->klass()->is_loaded() || (PatchALot && !x->is_incompatible_class_change_check() && !x->is_invokespecial_receiver_check())) {
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1273
    // must do this before locking the destination register as an oop register,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1274
    // and before the obj is loaded (the latter is for deoptimization)
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1275
    patching_info = state_for(x, x->state_before());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1276
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1277
  obj.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1278
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1279
  // info for exceptions
44738
11431bbc9549 8168699: Validate special case invocations
coleenp
parents: 42653
diff changeset
  1280
  CodeEmitInfo* info_for_exception =
11431bbc9549 8168699: Validate special case invocations
coleenp
parents: 42653
diff changeset
  1281
      (x->needs_exception_state() ? state_for(x) :
11431bbc9549 8168699: Validate special case invocations
coleenp
parents: 42653
diff changeset
  1282
                                    state_for(x, x->state_before(), true /*ignore_xhandler*/));
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1283
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1284
  CodeStub* stub;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1285
  if (x->is_incompatible_class_change_check()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1286
    assert(patching_info == NULL, "can't patch this");
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1287
    stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, LIR_OprFact::illegalOpr, info_for_exception);
44738
11431bbc9549 8168699: Validate special case invocations
coleenp
parents: 42653
diff changeset
  1288
  } else if (x->is_invokespecial_receiver_check()) {
11431bbc9549 8168699: Validate special case invocations
coleenp
parents: 42653
diff changeset
  1289
    assert(patching_info == NULL, "can't patch this");
11431bbc9549 8168699: Validate special case invocations
coleenp
parents: 42653
diff changeset
  1290
    stub = new DeoptimizeStub(info_for_exception,
11431bbc9549 8168699: Validate special case invocations
coleenp
parents: 42653
diff changeset
  1291
                              Deoptimization::Reason_class_check,
11431bbc9549 8168699: Validate special case invocations
coleenp
parents: 42653
diff changeset
  1292
                              Deoptimization::Action_none);
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1293
  } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1294
    stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1295
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1296
  LIR_Opr reg = rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1297
  LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1298
  if (!x->klass()->is_loaded() || UseCompressedClassPointers) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1299
    tmp3 = new_register(objectType);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1300
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1301
  __ checkcast(reg, obj.result(), x->klass(),
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1302
               new_register(objectType), new_register(objectType), tmp3,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1303
               x->direct_compare(), info_for_exception, patching_info, stub,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1304
               x->profiled_method(), x->profiled_bci());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1305
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1306
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1307
void LIRGenerator::do_InstanceOf(InstanceOf* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1308
  LIRItem obj(x->obj(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1309
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1310
  // result and test object may not be in same register
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1311
  LIR_Opr reg = rlock_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1312
  CodeEmitInfo* patching_info = NULL;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1313
  if ((!x->klass()->is_loaded() || PatchALot)) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1314
    // must do this before locking the destination register as an oop register
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1315
    patching_info = state_for(x, x->state_before());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1316
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1317
  obj.load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1318
  LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1319
  if (!x->klass()->is_loaded() || UseCompressedClassPointers) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1320
    tmp3 = new_register(objectType);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1321
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1322
  __ instanceof(reg, obj.result(), x->klass(),
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1323
                new_register(objectType), new_register(objectType), tmp3,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1324
                x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1325
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1326
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1327
void LIRGenerator::do_If(If* x) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1328
  assert(x->number_of_sux() == 2, "inconsistency");
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1329
  ValueTag tag = x->x()->type()->tag();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1330
  bool is_safepoint = x->is_safepoint();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1331
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1332
  If::Condition cond = x->cond();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1333
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1334
  LIRItem xitem(x->x(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1335
  LIRItem yitem(x->y(), this);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1336
  LIRItem* xin = &xitem;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1337
  LIRItem* yin = &yitem;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1338
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1339
  if (tag == longTag) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1340
    // for longs, only conditions "eql", "neq", "lss", "geq" are valid;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1341
    // mirror for other conditions
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1342
    if (cond == If::gtr || cond == If::leq) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1343
      cond = Instruction::mirror(cond);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1344
      xin = &yitem;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1345
      yin = &xitem;
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1346
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1347
    xin->set_destroys_register();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1348
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1349
  xin->load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1350
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1351
  if (tag == longTag) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1352
    if (yin->is_constant()
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1353
        && Assembler::operand_valid_for_add_sub_immediate(yin->get_jlong_constant())) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1354
      yin->dont_load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1355
    } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1356
      yin->load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1357
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1358
  } else if (tag == intTag) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1359
    if (yin->is_constant()
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1360
        && Assembler::operand_valid_for_add_sub_immediate(yin->get_jint_constant()))  {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1361
      yin->dont_load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1362
    } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1363
      yin->load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1364
    }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1365
  } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1366
    yin->load_item();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1367
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1368
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1369
  set_no_result(x);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1370
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1371
  LIR_Opr left = xin->result();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1372
  LIR_Opr right = yin->result();
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1373
50153
9010b580d8a9 8201447: C1 does backedge profiling incorrectly
iveresov
parents: 49933
diff changeset
  1374
  // add safepoint before generating condition code so it can be recomputed
9010b580d8a9 8201447: C1 does backedge profiling incorrectly
iveresov
parents: 49933
diff changeset
  1375
  if (x->is_safepoint()) {
9010b580d8a9 8201447: C1 does backedge profiling incorrectly
iveresov
parents: 49933
diff changeset
  1376
    // increment backedge counter if needed
9010b580d8a9 8201447: C1 does backedge profiling incorrectly
iveresov
parents: 49933
diff changeset
  1377
    increment_backedge_counter_conditionally(lir_cond(cond), left, right, state_for(x, x->state_before()),
9010b580d8a9 8201447: C1 does backedge profiling incorrectly
iveresov
parents: 49933
diff changeset
  1378
        x->tsux()->bci(), x->fsux()->bci(), x->profiled_bci());
9010b580d8a9 8201447: C1 does backedge profiling incorrectly
iveresov
parents: 49933
diff changeset
  1379
    __ safepoint(LIR_OprFact::illegalOpr, state_for(x, x->state_before()));
9010b580d8a9 8201447: C1 does backedge profiling incorrectly
iveresov
parents: 49933
diff changeset
  1380
  }
9010b580d8a9 8201447: C1 does backedge profiling incorrectly
iveresov
parents: 49933
diff changeset
  1381
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1382
  __ cmp(lir_cond(cond), left, right);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1383
  // Generate branch profiling. Profiling code doesn't kill flags.
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1384
  profile_branch(x, cond);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1385
  move_to_phi(x->state());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1386
  if (x->x()->type()->is_float_kind()) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1387
    __ branch(lir_cond(cond), right->type(), x->tsux(), x->usux());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1388
  } else {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1389
    __ branch(lir_cond(cond), right->type(), x->tsux());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1390
  }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1391
  assert(x->default_sux() == x->fsux(), "wrong destination above");
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1392
  __ jump(x->default_sux());
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1393
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1394
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1395
LIR_Opr LIRGenerator::getThreadPointer() {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1396
   return FrameMap::as_pointer_opr(rthread);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1397
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1398
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1399
void LIRGenerator::trace_block_entry(BlockBegin* block) { Unimplemented(); }
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1400
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1401
void LIRGenerator::volatile_field_store(LIR_Opr value, LIR_Address* address,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1402
                                        CodeEmitInfo* info) {
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1403
  __ volatile_store_mem_reg(value, address, info);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1404
}
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1405
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1406
void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result,
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1407
                                       CodeEmitInfo* info) {
45115
e3a622b2b7db 8179954: AArch64: C1 and C2 volatile accesses are not sequentially consistent
aph
parents: 44738
diff changeset
  1408
  // 8179954: We need to make sure that the code generated for
e3a622b2b7db 8179954: AArch64: C1 and C2 volatile accesses are not sequentially consistent
aph
parents: 44738
diff changeset
  1409
  // volatile accesses forms a sequentially-consistent set of
e3a622b2b7db 8179954: AArch64: C1 and C2 volatile accesses are not sequentially consistent
aph
parents: 44738
diff changeset
  1410
  // operations when combined with STLR and LDAR.  Without a leading
e3a622b2b7db 8179954: AArch64: C1 and C2 volatile accesses are not sequentially consistent
aph
parents: 44738
diff changeset
  1411
  // membar it's possible for a simple Dekker test to fail if loads
e3a622b2b7db 8179954: AArch64: C1 and C2 volatile accesses are not sequentially consistent
aph
parents: 44738
diff changeset
  1412
  // use LD;DMB but stores use STLR.  This can happen if C2 compiles
e3a622b2b7db 8179954: AArch64: C1 and C2 volatile accesses are not sequentially consistent
aph
parents: 44738
diff changeset
  1413
  // the stores in one method and C1 compiles the loads in another.
e3a622b2b7db 8179954: AArch64: C1 and C2 volatile accesses are not sequentially consistent
aph
parents: 44738
diff changeset
  1414
  if (! UseBarriersForVolatile) {
e3a622b2b7db 8179954: AArch64: C1 and C2 volatile accesses are not sequentially consistent
aph
parents: 44738
diff changeset
  1415
    __ membar();
e3a622b2b7db 8179954: AArch64: C1 and C2 volatile accesses are not sequentially consistent
aph
parents: 44738
diff changeset
  1416
  }
e3a622b2b7db 8179954: AArch64: C1 and C2 volatile accesses are not sequentially consistent
aph
parents: 44738
diff changeset
  1417
29184
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1418
  __ volatile_load_mem_reg(address, result, info);
e234025cafb6 8068053: AARCH64: C1 and C2 compilers
aph
parents:
diff changeset
  1419
}