src/hotspot/cpu/arm/assembler_arm_32.hpp
author lucy
Tue, 21 May 2019 15:51:35 +0200
changeset 54960 e46fe26d7f77
parent 54915 278600885731
permissions -rw-r--r--
8213084: Rework and enhance Print[Opto]Assembly output Reviewed-by: kvn, thartmann
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     1
/*
53244
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 52513
diff changeset
     2
 * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     4
 *
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     7
 * published by the Free Software Foundation.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     8
 *
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    13
 * accompanied this code).
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    14
 *
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    18
 *
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    21
 * questions.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    22
 *
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    23
 */
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    24
53244
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 52513
diff changeset
    25
#ifndef CPU_ARM_ASSEMBLER_ARM_32_HPP
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 52513
diff changeset
    26
#define CPU_ARM_ASSEMBLER_ARM_32_HPP
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    27
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    28
// ARM Addressing Mode 1 - Data processing operands
49364
601146c66cad 8173070: Remove ValueObj class for allocation subclassing for runtime code
coleenp
parents: 47216
diff changeset
    29
class AsmOperand {
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    30
 private:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    31
  int _encoding;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    32
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    33
  void initialize_rotated_imm(unsigned int imm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    34
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    35
  void encode(int imm_8) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    36
    if ((imm_8 >> 8) == 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    37
      _encoding = 1 << 25 | imm_8;  // the most common case
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    38
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    39
      initialize_rotated_imm((unsigned int)imm_8);  // slow case
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    40
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    41
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    42
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    43
  void encode(Register rm, AsmShift shift, int shift_imm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    44
    assert((shift_imm >> 5) == 0, "encoding constraint");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    45
    _encoding = shift_imm << 7 | shift << 5 | rm->encoding();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    46
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    47
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    48
 public:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    49
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    50
  AsmOperand(Register reg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    51
    _encoding = reg->encoding();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    52
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    53
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    54
  AsmOperand(int imm_8) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    55
    encode(imm_8);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    56
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    57
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    58
#ifdef ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    59
  AsmOperand(ByteSize bytesize_8) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    60
    const int imm_8 = in_bytes(bytesize_8);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    61
    encode(imm_8);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    62
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    63
#endif // ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    65
  AsmOperand(Register rm, AsmShift shift, int shift_imm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    66
    encode(rm,shift,shift_imm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    67
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    68
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    69
  AsmOperand(Register rm, AsmShift shift, Register rs) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    70
    assert(rm != PC && rs != PC, "unpredictable instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    71
    _encoding = rs->encoding() << 8 | shift << 5 | 1 << 4 | rm->encoding();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    72
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    73
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    74
  AsmOperand(RegisterOrConstant offset, AsmShift shift = lsl, int shift_imm = 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    75
    if (offset.is_register()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    76
      encode(offset.as_register(), shift, shift_imm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    77
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    78
      assert(shift == lsl,"shift type not yet encoded");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    79
      int imm_8 = ((int)offset.as_constant()) << shift_imm;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    80
      encode(imm_8);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    81
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    82
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    83
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    84
  int encoding() const {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    85
    return _encoding;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    86
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    87
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    88
  bool is_immediate() const {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    89
    return _encoding & (1 << 25) ? true : false;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    90
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    91
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    92
  Register base_register() const {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    93
    assert(!is_immediate(), "is_immediate, no base reg");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    94
    return as_Register(_encoding & 15);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    95
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    96
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    97
  static bool is_rotated_imm(unsigned int imm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    98
};
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    99
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   100
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   101
// ARM Addressing Mode 4 - Load and store multiple
49364
601146c66cad 8173070: Remove ValueObj class for allocation subclassing for runtime code
coleenp
parents: 47216
diff changeset
   102
class RegisterSet {
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   103
 private:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   104
  int _encoding;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   105
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   106
  RegisterSet(int encoding) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   107
    _encoding = encoding;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   108
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   109
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   110
 public:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   111
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   112
  RegisterSet(Register reg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   113
    _encoding = 1 << reg->encoding();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   114
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   115
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   116
  RegisterSet() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   117
    _encoding = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   118
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   119
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   120
  RegisterSet(Register first, Register last) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   121
    assert(first < last, "encoding constraint");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   122
    _encoding = (1 << (last->encoding() + 1)) - (1 << first->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   123
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   124
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   125
  friend RegisterSet operator | (const RegisterSet set1, const RegisterSet set2) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   126
    assert((set1._encoding & set2._encoding) == 0,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   127
           "encoding constraint");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   128
    return RegisterSet(set1._encoding | set2._encoding);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   129
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   130
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   131
  int encoding() const {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   132
    return _encoding;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   133
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   134
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   135
  bool contains(Register reg) const {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   136
    return (_encoding & (1 << reg->encoding())) != 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   137
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   138
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   139
  // number of registers in the set
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   140
  int size() const {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   141
    int count = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   142
    unsigned int remaining = (unsigned int) _encoding;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   143
    while (remaining != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   144
      if ((remaining & 1) != 0) count++;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   145
      remaining >>= 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   146
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   147
    return count;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   148
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   149
};
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   150
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   151
#if R9_IS_SCRATCHED
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   152
#define R9ifScratched RegisterSet(R9)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   153
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   154
#define R9ifScratched RegisterSet()
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   155
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   156
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   157
// ARM Addressing Mode 5 - Load and store multiple VFP registers
49364
601146c66cad 8173070: Remove ValueObj class for allocation subclassing for runtime code
coleenp
parents: 47216
diff changeset
   158
class FloatRegisterSet {
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   159
 private:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   160
  int _encoding;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   161
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   162
 public:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   163
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   164
  FloatRegisterSet(FloatRegister reg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   165
    if (reg->hi_bit() == 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   166
      _encoding = reg->hi_bits() << 12 | reg->lo_bit() << 22 | 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   167
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   168
      assert (reg->lo_bit() == 0, "impossible encoding");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   169
      _encoding = reg->hi_bits() << 12 | reg->hi_bit() << 22 | 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   170
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   171
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   172
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   173
  FloatRegisterSet(FloatRegister first, int count) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   174
    assert(count >= 1, "encoding constraint");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   175
    if (first->hi_bit() == 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   176
      _encoding = first->hi_bits() << 12 | first->lo_bit() << 22 | count;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   177
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   178
      assert (first->lo_bit() == 0, "impossible encoding");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   179
      _encoding = first->hi_bits() << 12 | first->hi_bit() << 22 | count;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   180
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   181
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   182
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   183
  int encoding_s() const {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   184
    return _encoding;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   185
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   186
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   187
  int encoding_d() const {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   188
    assert((_encoding & 0xFF) <= 16, "no more than 16 double registers" );
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   189
    return (_encoding & 0xFFFFFF00) | ((_encoding & 0xFF) << 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   190
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   191
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   192
};
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   193
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   194
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   195
class Assembler : public AbstractAssembler  {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   196
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   197
 public:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   198
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   199
  static const int LogInstructionSize = 2;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   200
  static const int InstructionSize    = 1 << LogInstructionSize;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   201
54960
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents: 54915
diff changeset
   202
  //---<  calculate length of instruction  >---
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents: 54915
diff changeset
   203
  // We just use the values set above.
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents: 54915
diff changeset
   204
  // instruction must start at passed address
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents: 54915
diff changeset
   205
  static unsigned int instr_len(unsigned char *instr) { return InstructionSize; }
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents: 54915
diff changeset
   206
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents: 54915
diff changeset
   207
  //---<  longest instructions  >---
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents: 54915
diff changeset
   208
  static unsigned int instr_maxlen() { return InstructionSize; }
e46fe26d7f77 8213084: Rework and enhance Print[Opto]Assembly output
lucy
parents: 54915
diff changeset
   209
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   210
  static inline AsmCondition inverse(AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   211
    assert ((cond != al) && (cond != nv), "AL and NV conditions cannot be inversed");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   212
    return (AsmCondition)((int)cond ^ 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   213
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   214
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   215
  // Returns true if given value can be used as immediate in arithmetic (add/sub/cmp/cmn) instructions.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   216
  static inline bool is_arith_imm_in_range(intx value) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   217
    return AsmOperand::is_rotated_imm(value);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   218
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   219
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   220
  // Arithmetic instructions
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   221
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   222
#define F(mnemonic, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   223
  void mnemonic(Register rd, Register rn, AsmOperand operand, AsmCondition cond = al) {    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   224
    emit_int32(cond << 28 | opcode << 21 | rn->encoding() << 16 |                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   225
               rd->encoding() << 12 | operand.encoding());                                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   226
  }                                                                                        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   227
  void mnemonic##s(Register rd, Register rn, AsmOperand operand, AsmCondition cond = al) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   228
    emit_int32(cond << 28 | opcode << 21 | 1 << 20 | rn->encoding() << 16 |                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   229
               rd->encoding() << 12 | operand.encoding());                                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   230
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   231
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   232
  F(andr, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   233
  F(eor,  1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   234
  F(sub,  2)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   235
  F(rsb,  3)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   236
  F(add,  4)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   237
  F(adc,  5)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   238
  F(sbc,  6)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   239
  F(rsc,  7)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   240
  F(orr,  12)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   241
  F(bic,  14)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   242
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   243
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   244
#define F(mnemonic, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   245
  void mnemonic(Register rn, AsmOperand operand, AsmCondition cond = al) {  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   246
    emit_int32(cond << 28 | opcode << 21 | 1 << 20 | rn->encoding() << 16 | \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   247
              operand.encoding());                                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   248
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   249
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   250
  F(tst, 8)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   251
  F(teq, 9)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   252
  F(cmp, 10)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   253
  F(cmn, 11)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   254
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   255
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   256
#define F(mnemonic, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   257
  void mnemonic(Register rd, AsmOperand operand, AsmCondition cond = al) {    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   258
    emit_int32(cond << 28 | opcode << 21 | rd->encoding() << 12 |             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   259
              operand.encoding());                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   260
  }                                                                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   261
  void mnemonic##s(Register rd, AsmOperand operand, AsmCondition cond = al) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   262
    emit_int32(cond << 28 | opcode << 21 | 1 << 20 | rd->encoding() << 12 |   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   263
              operand.encoding());                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   264
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   265
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   266
  F(mov, 13)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   267
  F(mvn, 15)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   268
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   269
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   270
  void msr(uint fields, AsmOperand operand, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   271
    assert((operand.encoding() & (1<<25)) || ((operand.encoding() & 0xff0) == 0), "invalid addressing mode");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   272
    emit_int32(cond << 28 | 1 << 24 | 1 << 21 | fields << 16 | 0xf << 12 | operand.encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   273
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   274
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   275
  void mrs(uint fields, Register Rd, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   276
    emit_int32(cond << 28 | 1 << 24 | (fields|0xf) << 16 | (Rd->encoding() << 12));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   277
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   278
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   279
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   280
  enum {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   281
    CPSR = 0x00, CPSR_c = 0x01, CPSR_x = 0x02, CPSR_xc = 0x03,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   282
    CPSR_s = 0x004, CPSR_sc = 0x05, CPSR_sx = 0x06, CPSR_sxc = 0x07,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   283
    CPSR_f = 0x08, CPSR_fc = 0x09, CPSR_fx = 0x0a, CPSR_fxc = 0x0b,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   284
    CPSR_fs = 0x0c, CPSR_fsc = 0x0d, CPSR_fsx = 0x0e, CPSR_fsxc = 0x0f,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   285
    SPSR = 0x40, SPSR_c = 0x41, SPSR_x = 0x42, SPSR_xc = 0x43,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   286
    SPSR_s = 0x44, SPSR_sc = 0x45, SPSR_sx = 0x46, SPSR_sxc = 0x47,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   287
    SPSR_f = 0x48, SPSR_fc = 0x49, SPSR_fx = 0x4a, SPSR_fxc = 0x4b,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   288
    SPSR_fs = 0x4c, SPSR_fsc = 0x4d, SPSR_fsx = 0x4e, SPSR_fsxc = 0x4f
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   289
  };
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   290
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   291
#define F(mnemonic, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   292
  void mnemonic(Register rdlo, Register rdhi, Register rm, Register rs,                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   293
                AsmCondition cond = al) {                                                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   294
    emit_int32(cond << 28 | opcode << 21 | rdhi->encoding() << 16 |                      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   295
              rdlo->encoding() << 12 | rs->encoding() << 8 | 0x9 << 4 | rm->encoding()); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   296
  }                                                                                      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   297
  void mnemonic##s(Register rdlo, Register rdhi, Register rm, Register rs,               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   298
                   AsmCondition cond = al) {                                             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   299
    emit_int32(cond << 28 | opcode << 21 | 1 << 20 | rdhi->encoding() << 16 |            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   300
              rdlo->encoding() << 12 | rs->encoding() << 8 | 0x9 << 4 | rm->encoding()); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   301
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   302
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   303
  F(umull, 4)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   304
  F(umlal, 5)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   305
  F(smull, 6)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   306
  F(smlal, 7)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   307
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   308
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   309
  void mul(Register rd, Register rm, Register rs, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   310
    emit_int32(cond << 28 | rd->encoding() << 16 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   311
              rs->encoding() << 8 | 0x9 << 4 | rm->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   312
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   313
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   314
  void muls(Register rd, Register rm, Register rs, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   315
    emit_int32(cond << 28 | 1 << 20 | rd->encoding() << 16 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   316
              rs->encoding() << 8 | 0x9 << 4 | rm->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   317
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   318
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   319
  void mla(Register rd, Register rm, Register rs, Register rn, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   320
    emit_int32(cond << 28 | 1 << 21 | rd->encoding() << 16 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   321
              rn->encoding() << 12 | rs->encoding() << 8 | 0x9 << 4 | rm->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   322
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   323
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   324
  void mlas(Register rd, Register rm, Register rs, Register rn, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   325
    emit_int32(cond << 28 | 1 << 21 | 1 << 20 | rd->encoding() << 16 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   326
              rn->encoding() << 12 | rs->encoding() << 8 | 0x9 << 4 | rm->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   327
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   328
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   329
  // Loads and stores
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   330
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   331
#define F(mnemonic, l, b) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   332
  void mnemonic(Register rd, Address addr, AsmCondition cond = al) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   333
    emit_int32(cond << 28 | 1 << 26 | b << 22 | l << 20 |            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   334
              rd->encoding() << 12 | addr.encoding2());              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   335
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   336
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   337
  F(ldr,  1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   338
  F(ldrb, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   339
  F(str,  0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   340
  F(strb, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   341
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   342
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   343
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   344
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   345
#define F(mnemonic, l, sh, even) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   346
  void mnemonic(Register rd, Address addr, AsmCondition cond = al) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   347
    assert(!even || (rd->encoding() & 1) == 0, "must be even");      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   348
    emit_int32(cond << 28 | l << 20 | rd->encoding() << 12 |         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   349
              1 << 7 | sh << 5 | 1 << 4 | addr.encoding3());         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   350
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   351
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   352
  F(strh,  0, 1, false)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   353
  F(ldrh,  1, 1, false)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   354
  F(ldrsb, 1, 2, false)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   355
  F(ldrsh, 1, 3, false)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   356
  F(strd,  0, 3, true)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   357
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   358
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   359
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   360
  void ldrd(Register rd, Address addr, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   361
    assert((rd->encoding() & 1) == 0, "must be even");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   362
    assert(!addr.index()->is_valid() ||
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   363
           (addr.index()->encoding() != rd->encoding() &&
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   364
            addr.index()->encoding() != (rd->encoding()+1)), "encoding constraint");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   365
    emit_int32(cond << 28 | rd->encoding() << 12 | 0xD /* 0b1101 */ << 4 | addr.encoding3());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   366
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   367
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   368
#define F(mnemonic, l, pu) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   369
  void mnemonic(Register rn, RegisterSet reg_set,                        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   370
                AsmWriteback w = no_writeback, AsmCondition cond = al) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   371
    assert(reg_set.encoding() != 0 && (w == no_writeback ||              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   372
           (reg_set.encoding() & (1 << rn->encoding())) == 0),           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   373
           "unpredictable instruction");                                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   374
    emit_int32(cond << 28 | 4 << 25 | pu << 23 | w << 21 | l << 20 |     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   375
              rn->encoding() << 16 | reg_set.encoding());                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   376
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   377
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   378
  F(ldmda, 1, 0)    F(ldmfa, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   379
  F(ldmia, 1, 1)    F(ldmfd, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   380
  F(ldmdb, 1, 2)    F(ldmea, 1, 2)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   381
  F(ldmib, 1, 3)    F(ldmed, 1, 3)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   382
  F(stmda, 0, 0)    F(stmed, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   383
  F(stmia, 0, 1)    F(stmea, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   384
  F(stmdb, 0, 2)    F(stmfd, 0, 2)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   385
  F(stmib, 0, 3)    F(stmfa, 0, 3)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   386
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   387
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   388
  void ldrex(Register rd, Address addr, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   389
    assert(rd != PC, "unpredictable instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   390
    emit_int32(cond << 28 | 0x19 << 20 | addr.encoding_ex() |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   391
              rd->encoding()  << 12 | 0xf9f);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   392
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   393
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   394
  void strex(Register rs, Register rd, Address addr, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   395
    assert(rd != PC && rs != PC &&
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   396
           rs != rd && rs != addr.base(), "unpredictable instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   397
    emit_int32(cond << 28 | 0x18 << 20 | addr.encoding_ex() |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   398
              rs->encoding()  << 12 | 0xf90 | rd->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   399
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   400
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   401
  void ldrexd(Register rd, Address addr, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   402
    assert(rd != PC, "unpredictable instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   403
    emit_int32(cond << 28 | 0x1B << 20 | addr.encoding_ex() |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   404
              rd->encoding()  << 12 | 0xf9f);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   405
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   406
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   407
  void strexd(Register rs, Register rd, Address addr, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   408
    assert(rd != PC && rs != PC &&
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   409
           rs != rd && rs != addr.base(), "unpredictable instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   410
    emit_int32(cond << 28 | 0x1A << 20 | addr.encoding_ex() |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   411
              rs->encoding()  << 12 | 0xf90 | rd->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   412
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   413
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   414
  void clrex() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   415
    emit_int32(0xF << 28 | 0x57 << 20 | 0xFF  << 12 | 0x01f);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   416
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   417
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   418
  // Miscellaneous instructions
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   419
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   420
  void clz(Register rd, Register rm, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   421
    emit_int32(cond << 28 | 0x016f0f10 | rd->encoding() << 12 | rm->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   422
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   423
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   424
  void rev(Register rd, Register rm, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   425
    emit_int32(cond << 28 | 0x06bf0f30 | rd->encoding() << 12 | rm->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   426
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   427
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   428
  void rev16(Register rd, Register rm, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   429
    emit_int32(cond << 28 | 0x6bf0fb0 | rd->encoding() << 12 | rm->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   430
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   431
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   432
  void revsh(Register rd, Register rm, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   433
    emit_int32(cond << 28 | 0x6ff0fb0 | rd->encoding() << 12 | rm->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   434
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   435
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   436
  void rbit(Register rd, Register rm, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   437
    emit_int32(cond << 28 | 0x6ff0f30 | rd->encoding() << 12 | rm->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   438
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   439
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   440
  void pld(Address addr) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   441
    emit_int32(0xf550f000 | addr.encoding2());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   442
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   443
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   444
  void pldw(Address addr) {
54915
278600885731 8222825: ARM32 SIGILL issue on single core CPU (not supported PLDW instruction)
bulasevich
parents: 53244
diff changeset
   445
    assert(!VM_Version::is_initialized() ||
278600885731 8222825: ARM32 SIGILL issue on single core CPU (not supported PLDW instruction)
bulasevich
parents: 53244
diff changeset
   446
           (VM_Version::arm_arch() >= 7 && VM_Version::has_multiprocessing_extensions()),
278600885731 8222825: ARM32 SIGILL issue on single core CPU (not supported PLDW instruction)
bulasevich
parents: 53244
diff changeset
   447
           "PLDW is available on ARMv7 with Multiprocessing Extensions only");
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   448
    emit_int32(0xf510f000 | addr.encoding2());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   449
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   450
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   451
  void svc(int imm_24, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   452
    assert((imm_24 >> 24) == 0, "encoding constraint");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   453
    emit_int32(cond << 28 | 0xf << 24 | imm_24);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   454
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   455
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   456
  void ubfx(Register rd, Register rn, unsigned int lsb, unsigned int width, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   457
    assert(VM_Version::arm_arch() >= 7, "no ubfx on this processor");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   458
    assert(width > 0, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   459
    assert(lsb < 32, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   460
    emit_int32(cond << 28 | 0x3f << 21 | (width - 1)  << 16 | rd->encoding() << 12 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   461
              lsb << 7 | 0x5 << 4 | rn->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   462
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   463
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   464
  void uxtb(Register rd, Register rm, unsigned int rotation = 0, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   465
    assert(VM_Version::arm_arch() >= 7, "no uxtb on this processor");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   466
    assert((rotation % 8) == 0 && (rotation <= 24), "encoding constraint");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   467
    emit_int32(cond << 28 | 0x6e << 20 | 0xf << 16 | rd->encoding() << 12 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   468
              (rotation >> 3) << 10 | 0x7 << 4 | rm->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   469
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   470
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   471
  // ARM Memory Barriers
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   472
  //
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   473
  // There are two types of memory barriers defined for the ARM processor
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   474
  // DataSynchronizationBarrier and DataMemoryBarrier
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   475
  //
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   476
  // The Linux kernel uses the DataMemoryBarrier for all of it's
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   477
  // memory barrier operations (smp_mb, smp_rmb, smp_wmb)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   478
  //
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   479
  // There are two forms of each barrier instruction.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   480
  // The mcr forms are supported on armv5 and newer architectures
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   481
  //
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   482
  // The dmb, dsb instructions were added in armv7
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   483
  // architectures and are compatible with their mcr
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   484
  // predecessors.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   485
  //
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   486
  // Here are the encodings for future reference:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   487
  //
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   488
  // DataSynchronizationBarrier (dsb)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   489
  // on ARMv7 - emit_int32(0xF57FF04F)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   490
  //
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   491
  // on ARMv5+ - mcr p15, 0, Rtmp, c7, c10, 4  on earlier processors
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   492
  //             emit_int32(0xe << 28 | 0xe << 24 | 0x7 << 16 | Rtmp->encoding() << 12  |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   493
  //                       0xf << 8  | 0x9 << 4  | 0xa);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   494
  //
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   495
  // DataMemoryBarrier (dmb)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   496
  // on ARMv7 - emit_int32(0xF57FF05F)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   497
  //
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   498
  // on ARMv5+ - mcr p15, 0, Rtmp, c7, c10, 5 on earlier processors
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   499
  //             emit_int32(0xe << 28 | 0xe << 24 | 0x7 << 16 | Rtmp->encoding() << 12  |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   500
  //                       0xf << 8  | 0xb << 4  | 0xa);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   501
  //
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   502
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   503
  enum DMB_Opt {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   504
    DMB_all = 0xf,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   505
    DMB_st  = 0xe,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   506
  };
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   507
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   508
  void dmb(DMB_Opt opt, Register reg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   509
    if (VM_Version::arm_arch() >= 7) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   510
      emit_int32(0xF57FF050 | opt);
52513
d4f3e37d1fda 8213826: Disable ARMv6 memory barriers on ARMv5 processors
dholmes
parents: 51381
diff changeset
   511
    } else if (VM_Version::arm_arch() == 6) {
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   512
      bool preserve_tmp = (reg == noreg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   513
      if(preserve_tmp) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   514
        reg = Rtemp;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   515
        str(reg, Address(SP, -wordSize, pre_indexed));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   516
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   517
      mov(reg, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   518
      // DataMemoryBarrier
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   519
      emit_int32(0xe << 28 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   520
                0xe << 24 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   521
                0x7 << 16 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   522
                reg->encoding() << 12  |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   523
                0xf << 8  |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   524
                0xb << 4  |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   525
                0xa);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   526
      if(preserve_tmp) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   527
        ldr(reg, Address(SP, wordSize, post_indexed));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   528
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   529
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   530
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   531
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   532
  void dsb(Register reg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   533
    if (VM_Version::arm_arch() >= 7) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   534
      emit_int32(0xF57FF04F);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   535
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   536
      bool preserve_tmp = (reg == noreg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   537
      if(preserve_tmp) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   538
        reg = Rtemp;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   539
        str(reg, Address(SP, -wordSize, pre_indexed));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   540
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   541
      mov(reg, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   542
      // DataSynchronizationBarrier
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   543
      emit_int32(0xe << 28 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   544
                0xe << 24 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   545
                0x7 << 16 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   546
                reg->encoding() << 12  |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   547
                0xf << 8  |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   548
                0x9 << 4  |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   549
                0xa);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   550
      if(preserve_tmp) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   551
        ldr(reg, Address(SP, wordSize, post_indexed));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   552
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   553
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   554
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   555
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   556
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   557
#define F(mnemonic, b) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   558
  void mnemonic(Register rd, Register rm, Register rn, AsmCondition cond = al) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   559
    assert(rn != rm && rn != rd, "unpredictable instruction");                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   560
    emit_int32(cond << 28 | 0x2 << 23 | b << 22 | rn->encoding() << 16 |         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   561
              rd->encoding() << 12 | 9 << 4 | rm->encoding());                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   562
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   563
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   564
  F(swp,  0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   565
  F(swpb, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   566
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   567
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   568
  // Branches
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   569
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   570
#define F(mnemonic, l) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   571
  void mnemonic(Register rm, AsmCondition cond = al) {            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   572
    emit_int32(cond << 28 | 0x012fff10 | l << 5 | rm->encoding()); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   573
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   574
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   575
  F(bx,  0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   576
  F(blx, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   577
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   578
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   579
#define F(mnemonic, l)                                                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   580
  void mnemonic(address target, AsmCondition cond = al) {               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   581
    unsigned int offset = (unsigned int)(target - pc() - 8);            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   582
    assert((offset & 3) == 0, "bad alignment");                         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   583
    assert((offset >> 25) == 0 || ((int)offset >> 25) == -1, "offset is too large"); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   584
    emit_int32(cond << 28 | l << 24 | offset << 6 >> 8);                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   585
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   586
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   587
  F(b,  0xa)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   588
  F(bl, 0xb)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   589
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   590
46525
3a5c833a43de 8176506: C2: loop unswitching and unsafe accesses cause crash
roland
parents: 42664
diff changeset
   591
  void udf(int imm_16) {
3a5c833a43de 8176506: C2: loop unswitching and unsafe accesses cause crash
roland
parents: 42664
diff changeset
   592
    assert((imm_16 >> 16) == 0, "encoding constraint");
3a5c833a43de 8176506: C2: loop unswitching and unsafe accesses cause crash
roland
parents: 42664
diff changeset
   593
    emit_int32(0xe7f000f0 | (imm_16 & 0xfff0) << 8 | (imm_16 & 0xf));
3a5c833a43de 8176506: C2: loop unswitching and unsafe accesses cause crash
roland
parents: 42664
diff changeset
   594
  }
3a5c833a43de 8176506: C2: loop unswitching and unsafe accesses cause crash
roland
parents: 42664
diff changeset
   595
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   596
  // ARMv7 instructions
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   597
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   598
#define F(mnemonic, wt) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   599
  void mnemonic(Register rd, int imm_16, AsmCondition cond = al) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   600
    assert((imm_16 >> 16) == 0, "encoding constraint");            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   601
    emit_int32(cond << 28 | wt << 20 | rd->encoding() << 12 |      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   602
              (imm_16 & 0xf000) << 4 | (imm_16 & 0xfff));          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   603
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   604
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   605
  F(movw, 0x30)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   606
  F(movt, 0x34)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   607
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   608
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   609
  // VFP Support
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   610
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   611
// Checks that VFP instructions are not used in SOFTFP mode.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   612
#ifdef __SOFTFP__
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   613
#define CHECK_VFP_PRESENT ShouldNotReachHere()
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   614
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   615
#define CHECK_VFP_PRESENT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   616
#endif // __SOFTFP__
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   617
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   618
  static const int single_cp_num = 0xa00;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   619
  static const int double_cp_num = 0xb00;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   620
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   621
  // Bits P, Q, R, S collectively form the opcode
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   622
#define F(mnemonic, P, Q, R, S) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   623
  void mnemonic##d(FloatRegister fd, FloatRegister fn, FloatRegister fm, \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   624
                   AsmCondition cond = al) {                             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   625
    CHECK_VFP_PRESENT;                                                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   626
    assert(fn->lo_bit() == 0 && fd->lo_bit() == 0 && fm->lo_bit() == 0, "single precision register?"); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   627
    emit_int32(cond << 28 | 0x7 << 25 | double_cp_num |                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   628
              P << 23 | Q << 21 | R << 20 | S << 6 |                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   629
              fn->hi_bits() << 16 | fn->hi_bit() << 7 |                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   630
              fd->hi_bits() << 12 | fd->hi_bit() << 22 |                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   631
              fm->hi_bits()       | fm->hi_bit() << 5);                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   632
  }                                                                      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   633
  void mnemonic##s(FloatRegister fd, FloatRegister fn, FloatRegister fm, \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   634
                   AsmCondition cond = al) {                             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   635
    assert(fn->hi_bit() == 0 && fd->hi_bit() == 0 && fm->hi_bit() == 0, "double precision register?"); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   636
    CHECK_VFP_PRESENT;                                                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   637
    emit_int32(cond << 28 | 0x7 << 25 | single_cp_num |                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   638
              P << 23 | Q << 21 | R << 20 | S << 6 |                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   639
              fn->hi_bits() << 16 | fn->lo_bit() << 7 |                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   640
              fd->hi_bits() << 12 | fd->lo_bit() << 22 |                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   641
              fm->hi_bits()       | fm->lo_bit() << 5);                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   642
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   643
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   644
  F(fmac,  0, 0, 0, 0)  // Fd = Fd + (Fn * Fm)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   645
  F(fnmac, 0, 0, 0, 1)  // Fd = Fd - (Fn * Fm)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   646
  F(fmsc,  0, 0, 1, 0)  // Fd = -Fd + (Fn * Fm)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   647
  F(fnmsc, 0, 0, 1, 1)  // Fd = -Fd - (Fn * Fm)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   648
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   649
  F(fmul,  0, 1, 0, 0)  // Fd = Fn * Fm
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   650
  F(fnmul, 0, 1, 0, 1)  // Fd = -(Fn * Fm)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   651
  F(fadd,  0, 1, 1, 0)  // Fd = Fn + Fm
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   652
  F(fsub,  0, 1, 1, 1)  // Fd = Fn - Fm
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   653
  F(fdiv,  1, 0, 0, 0)  // Fd = Fn / Fm
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   654
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   655
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   656
  enum VElem_Size {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   657
    VELEM_SIZE_8  = 0x00,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   658
    VELEM_SIZE_16 = 0x01,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   659
    VELEM_SIZE_32 = 0x02,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   660
    VELEM_SIZE_64 = 0x03
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   661
  };
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   662
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   663
  enum VLD_Type {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   664
    VLD1_TYPE_1_REG  = 0x7 /* 0b0111 */,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   665
    VLD1_TYPE_2_REGS = 0xA /* 0b1010 */,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   666
    VLD1_TYPE_3_REGS = 0x6 /* 0b0110 */,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   667
    VLD1_TYPE_4_REGS = 0x2 /* 0b0010 */
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   668
  };
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   669
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   670
  enum VFloat_Arith_Size {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   671
    VFA_SIZE_F32 = 0x0 /* 0b0 */,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   672
  };
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   673
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   674
  // Bits P, Q, R, S collectively form the opcode
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   675
#define F(mnemonic, P, Q, R, S) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   676
  void mnemonic(FloatRegister fd, FloatRegister fn, FloatRegister fm,    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   677
                int size, int quad) {                                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   678
    CHECK_VFP_PRESENT;                                                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   679
    assert(VM_Version::has_simd(), "simd instruction");                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   680
    assert(fn->lo_bit() == 0 && fd->lo_bit() == 0 && fm->lo_bit() == 0,  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   681
           "single precision register?");                                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   682
    assert(!quad || ((fn->hi_bits() | fd->hi_bits() | fm->hi_bits()) & 1) == 0, \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   683
           "quad precision register?");                                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   684
    emit_int32(0xf << 28 | P << 23 | Q << 8 | R << 4 |                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   685
              S << 21 | size << 20 | quad << 6 |                         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   686
              fn->hi_bits() << 16 | fn->hi_bit() << 7 |                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   687
              fd->hi_bits() << 12 | fd->hi_bit() << 22 |                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   688
              fm->hi_bits()       | fm->hi_bit() << 5);                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   689
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   690
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   691
  F(vmulI,  0x4 /* 0b0100 */, 0x9 /* 0b1001 */, 1, 0)  // Vd = Vn * Vm (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   692
  F(vaddI,  0x4 /* 0b0100 */, 0x8 /* 0b1000 */, 0, 0)  // Vd = Vn + Vm (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   693
  F(vsubI,  0x6 /* 0b0110 */, 0x8 /* 0b1000 */, 0, 0)  // Vd = Vn - Vm (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   694
  F(vaddF,  0x4 /* 0b0100 */, 0xD /* 0b1101 */, 0, 0)  // Vd = Vn + Vm (float)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   695
  F(vsubF,  0x4 /* 0b0100 */, 0xD /* 0b1101 */, 0, 1)  // Vd = Vn - Vm (float)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   696
  F(vmulF,  0x6 /* 0b0110 */, 0xD /* 0b1101 */, 1, 0)  // Vd = Vn * Vm (float)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   697
  F(vshlSI, 0x4 /* 0b0100 */, 0x4 /* 0b0100 */, 0, 0)  // Vd = ashift(Vm,Vn) (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   698
  F(vshlUI, 0x6 /* 0b0110 */, 0x4 /* 0b0100 */, 0, 0)  // Vd = lshift(Vm,Vn) (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   699
  F(_vandI, 0x4 /* 0b0100 */, 0x1 /* 0b0001 */, 1, 0)  // Vd = Vn & Vm (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   700
  F(_vorI,  0x4 /* 0b0100 */, 0x1 /* 0b0001 */, 1, 1)  // Vd = Vn | Vm (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   701
  F(_vxorI, 0x6 /* 0b0110 */, 0x1 /* 0b0001 */, 1, 0)  // Vd = Vn ^ Vm (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   702
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   703
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   704
  void vandI(FloatRegister fd, FloatRegister fn, FloatRegister fm, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   705
    _vandI(fd, fn, fm, 0, quad);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   706
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   707
  void vorI(FloatRegister fd, FloatRegister fn, FloatRegister fm, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   708
    _vorI(fd, fn, fm, 0, quad);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   709
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   710
  void vxorI(FloatRegister fd, FloatRegister fn, FloatRegister fm, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   711
    _vxorI(fd, fn, fm, 0, quad);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   712
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   713
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   714
  void vneg(FloatRegister fd, FloatRegister fm, int size, int flt, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   715
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   716
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   717
    assert(fd->lo_bit() == 0 && fm->lo_bit() == 0,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   718
           "single precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   719
    assert(!quad || ((fd->hi_bits() | fm->hi_bits()) & 1) == 0,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   720
           "quad precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   721
    emit_int32(0xf << 28 | 0x3B /* 0b00111011 */ << 20 | 0x1 /* 0b01 */ << 16 | 0x7 /* 0b111 */ << 7 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   722
               size << 18 | quad << 6 | flt << 10 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   723
               fd->hi_bits() << 12 | fd->hi_bit() << 22 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   724
               fm->hi_bits() <<  0 | fm->hi_bit() << 5);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   725
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   726
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   727
  void vnegI(FloatRegister fd, FloatRegister fm, int size, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   728
    int flt = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   729
    vneg(fd, fm, size, flt, quad);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   730
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   731
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   732
  void vshli(FloatRegister fd, FloatRegister fm, int size, int imm, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   733
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   734
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   735
    assert(fd->lo_bit() == 0 && fm->lo_bit() == 0,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   736
           "single precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   737
    assert(!quad || ((fd->hi_bits() | fm->hi_bits()) & 1) == 0,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   738
           "quad precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   739
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   740
    if (imm >= size) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   741
      // maximum shift gives all zeroes, direction doesn't matter,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   742
      // but only available for shift right
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   743
      vshri(fd, fm, size, size, true /* unsigned */, quad);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   744
      return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   745
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   746
    assert(imm >= 0 && imm < size, "out of range");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   747
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   748
    int imm6 = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   749
    int L = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   750
    switch (size) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   751
    case 8:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   752
    case 16:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   753
    case 32:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   754
      imm6 = size + imm ;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   755
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   756
    case 64:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   757
      L = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   758
      imm6 = imm ;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   759
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   760
    default:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   761
      ShouldNotReachHere();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   762
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   763
    emit_int32(0xf << 28 | 0x5 /* 0b00101 */ << 23 | 0x51 /* 0b01010001 */ << 4 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   764
               imm6 << 16 | L << 7 | quad << 6 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   765
               fd->hi_bits() << 12 | fd->hi_bit() << 22 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   766
               fm->hi_bits() <<  0 | fm->hi_bit() << 5);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   767
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   768
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   769
  void vshri(FloatRegister fd, FloatRegister fm, int size, int imm,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   770
             bool U /* unsigned */, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   771
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   772
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   773
    assert(fd->lo_bit() == 0 && fm->lo_bit() == 0,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   774
           "single precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   775
    assert(!quad || ((fd->hi_bits() | fm->hi_bits()) & 1) == 0,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   776
           "quad precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   777
    assert(imm > 0, "out of range");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   778
    if (imm >= size) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   779
      // maximum shift (all zeroes)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   780
      imm = size;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   781
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   782
    int imm6 = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   783
    int L = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   784
    switch (size) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   785
    case 8:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   786
    case 16:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   787
    case 32:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   788
      imm6 = 2 * size - imm ;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   789
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   790
    case 64:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   791
      L = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   792
      imm6 = 64 - imm ;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   793
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   794
    default:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   795
      ShouldNotReachHere();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   796
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   797
    emit_int32(0xf << 28 | 0x5 /* 0b00101 */ << 23 | 0x1 /* 0b00000001 */ << 4 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   798
               imm6 << 16 | L << 7 | quad << 6 | U << 24 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   799
               fd->hi_bits() << 12 | fd->hi_bit() << 22 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   800
               fm->hi_bits() <<  0 | fm->hi_bit() << 5);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   801
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   802
  void vshrUI(FloatRegister fd, FloatRegister fm, int size, int imm, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   803
    vshri(fd, fm, size, imm, true /* unsigned */, quad);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   804
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   805
  void vshrSI(FloatRegister fd, FloatRegister fm, int size, int imm, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   806
    vshri(fd, fm, size, imm, false /* signed */, quad);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   807
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   808
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   809
  // Extension opcodes where P,Q,R,S = 1 opcode is in Fn
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   810
#define F(mnemonic, N, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   811
  void mnemonic##d(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   812
    CHECK_VFP_PRESENT;                                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   813
    assert(fd->lo_bit() == 0 && fm->hi_bit() == 0, "incorrect register?");        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   814
    emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   815
              double_cp_num |                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   816
              fd->hi_bits() << 12 | fd->hi_bit() << 22 |                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   817
              fm->hi_bits()       | fm->lo_bit() << 5);                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   818
  }                                                                               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   819
  void mnemonic##s(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   820
    CHECK_VFP_PRESENT;                                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   821
    assert(fd->hi_bit() == 0 && fm->hi_bit() == 0, "double precision register?"); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   822
    emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   823
              single_cp_num |                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   824
              fd->hi_bits() << 12 | fd->lo_bit() << 22 |                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   825
              fm->hi_bits()       | fm->lo_bit() << 5);                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   826
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   827
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   828
  F(fuito,  0, 0x8)  // Unsigned integer to floating point conversion
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   829
  F(fsito,  1, 0x8)  // Signed integer to floating point conversion
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   830
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   831
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   832
#define F(mnemonic, N, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   833
  void mnemonic##d(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   834
    CHECK_VFP_PRESENT;                                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   835
    assert(fd->hi_bit() == 0 && fm->lo_bit() == 0, "incorrect register?");        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   836
    emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   837
              double_cp_num |                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   838
              fd->hi_bits() << 12 | fd->lo_bit() << 22 |                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   839
              fm->hi_bits()       | fm->hi_bit() << 5);                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   840
  }                                                                               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   841
  void mnemonic##s(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   842
    CHECK_VFP_PRESENT;                                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   843
    assert(fd->hi_bit() == 0 && fm->hi_bit() == 0, "double precision register?"); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   844
    emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   845
              single_cp_num |                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   846
              fd->hi_bits() << 12 | fd->lo_bit() << 22 |                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   847
              fm->hi_bits()       | fm->lo_bit() << 5);                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   848
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   849
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   850
  F(ftoui,  0, 0xc)  // Float to unsigned int conversion
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   851
  F(ftouiz, 1, 0xc)  // Float to unsigned int conversion, RZ mode
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   852
  F(ftosi,  0, 0xd)  // Float to signed int conversion
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   853
  F(ftosiz, 1, 0xd)  // Float to signed int conversion, RZ mode
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   854
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   855
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   856
#define F(mnemonic, N, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   857
  void mnemonic##d(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   858
    CHECK_VFP_PRESENT;                                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   859
    assert(fd->hi_bit() == 0 && fm->lo_bit() == 0, "incorrect register?");        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   860
    emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   861
              double_cp_num |                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   862
              fd->hi_bits() << 12 | fd->lo_bit() << 22 |                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   863
              fm->hi_bits()       | fm->hi_bit() << 5);                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   864
  }                                                                               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   865
  void mnemonic##s(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   866
    CHECK_VFP_PRESENT;                                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   867
    assert(fd->lo_bit() == 0 && fm->hi_bit() == 0, "incorrect register?");        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   868
    emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   869
              single_cp_num |                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   870
              fd->hi_bits() << 12 | fd->hi_bit() << 22 |                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   871
              fm->hi_bits()       | fm->lo_bit() << 5);                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   872
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   873
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   874
  F(fcvtd,  1, 0x7)  // Single->Double conversion
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   875
  F(fcvts,  1, 0x7)  // Double->Single conversion
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   876
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   877
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   878
#define F(mnemonic, N, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   879
  void mnemonic##d(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   880
    CHECK_VFP_PRESENT;                                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   881
    assert(fd->lo_bit() == 0 && fm->lo_bit() == 0, "single precision register?"); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   882
    emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   883
              double_cp_num |                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   884
              fd->hi_bits() << 12 | fd->hi_bit() << 22 |                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   885
              fm->hi_bits()       | fm->hi_bit() << 5);                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   886
  }                                                                               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   887
  void mnemonic##s(FloatRegister fd, FloatRegister fm, AsmCondition cond = al) {  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   888
    CHECK_VFP_PRESENT;                                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   889
    assert(fd->hi_bit() == 0 && fm->hi_bit() == 0, "double precision register?"); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   890
    emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   891
              single_cp_num |                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   892
              fd->hi_bits() << 12 | fd->lo_bit() << 22 |                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   893
              fm->hi_bits()       | fm->lo_bit() << 5);                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   894
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   895
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   896
  F(fcpy,   0, 0x0)  // Fd = Fm
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   897
  F(fabs,   1, 0x0)  // Fd = abs(Fm)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   898
  F(fneg,   0, 0x1)  // Fd = -Fm
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   899
  F(fsqrt,  1, 0x1)  // Fd = sqrt(Fm)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   900
  F(fcmp,   0, 0x4)  // Compare Fd with Fm no exceptions on quiet NANs
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   901
  F(fcmpe,  1, 0x4)  // Compare Fd with Fm with exceptions on quiet NANs
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   902
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   903
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   904
  // Opcodes with one operand only
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   905
#define F(mnemonic, N, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   906
  void mnemonic##d(FloatRegister fd, AsmCondition cond = al) {               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   907
    CHECK_VFP_PRESENT;                                                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   908
    assert(fd->lo_bit() == 0, "single precision register?");                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   909
    emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   910
              double_cp_num | fd->hi_bits() << 12 | fd->hi_bit() << 22);     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   911
  }                                                                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   912
  void mnemonic##s(FloatRegister fd, AsmCondition cond = al) {               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   913
    CHECK_VFP_PRESENT;                                                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   914
    assert(fd->hi_bit() == 0, "double precision register?");                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   915
    emit_int32(cond << 28 | 0xeb << 20 | opcode << 16 | N << 7 | 1 << 6 |    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   916
              single_cp_num | fd->hi_bits() << 12 | fd->lo_bit() << 22);     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   917
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   918
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   919
  F(fcmpz,  0, 0x5)  // Compare Fd with 0, no exceptions quiet NANs
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   920
  F(fcmpez, 1, 0x5)  // Compare Fd with 0, with exceptions quiet NANs
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   921
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   922
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   923
  // Float loads (L==1) and stores (L==0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   924
#define F(mnemonic, L) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   925
  void mnemonic##d(FloatRegister fd, Address addr, AsmCondition cond = al) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   926
    CHECK_VFP_PRESENT;                                                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   927
    assert(fd->lo_bit() == 0, "single precision register?");                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   928
    emit_int32(cond << 28 | 0xd << 24 | L << 20 |                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   929
              fd->hi_bits() << 12 | fd->hi_bit() << 22 |                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   930
              double_cp_num | addr.encoding_vfp());                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   931
  }                                                                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   932
  void mnemonic##s(FloatRegister fd, Address addr, AsmCondition cond = al) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   933
    CHECK_VFP_PRESENT;                                                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   934
    assert(fd->hi_bit() == 0, "double precision register?");                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   935
    emit_int32(cond << 28 | 0xd << 24 | L << 20 |                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   936
              fd->hi_bits() << 12 | fd->lo_bit() << 22 |                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   937
              single_cp_num | addr.encoding_vfp());                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   938
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   939
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   940
  F(fst, 0)  // Store 1 register
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   941
  F(fld, 1)  // Load 1 register
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   942
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   943
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   944
  // Float load and store multiple
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   945
#define F(mnemonic, l, pu) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   946
  void mnemonic##d(Register rn, FloatRegisterSet reg_set,                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   947
                   AsmWriteback w = no_writeback, AsmCondition cond = al) {  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   948
    CHECK_VFP_PRESENT;                                                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   949
    assert(w == no_writeback || rn != PC, "unpredictable instruction");      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   950
    assert(!(w == no_writeback && pu == 2), "encoding constraint");          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   951
    assert((reg_set.encoding_d() & 1) == 0, "encoding constraint");          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   952
    emit_int32(cond << 28 | 6 << 25 | pu << 23 | w << 21 | l << 20 |         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   953
              rn->encoding() << 16 | reg_set.encoding_d() | double_cp_num);  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   954
  }                                                                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   955
  void mnemonic##s(Register rn, FloatRegisterSet reg_set,                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   956
                   AsmWriteback w = no_writeback, AsmCondition cond = al) {  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   957
    CHECK_VFP_PRESENT;                                                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   958
    assert(w == no_writeback || rn != PC, "unpredictable instruction");      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   959
    assert(!(w == no_writeback && pu == 2), "encoding constraint");          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   960
    emit_int32(cond << 28 | 6 << 25 | pu << 23 | w << 21 | l << 20 |         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   961
              rn->encoding() << 16 | reg_set.encoding_s() | single_cp_num);  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   962
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   963
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   964
  F(fldmia, 1, 1)    F(fldmfd, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   965
  F(fldmdb, 1, 2)    F(fldmea, 1, 2)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   966
  F(fstmia, 0, 1)    F(fstmfd, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   967
  F(fstmdb, 0, 2)    F(fstmea, 0, 2)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   968
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   969
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   970
  // fconst{s,d} encoding:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   971
  //  31  28 27   23 22  21 20 19   16 15 12 10  9  8   7    4 3     0
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   972
  // | cond | 11101 | D | 11  | imm4H | Vd  | 101 | sz | 0000 | imm4L |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   973
  // sz = 0 for single precision, 1 otherwise
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   974
  // Register number is Vd:D for single precision, D:Vd otherwise
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   975
  // immediate value is imm4H:imm4L
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   976
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   977
  void fconsts(FloatRegister fd, unsigned char imm_8, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   978
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   979
    assert(fd->hi_bit() == 0, "double precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   980
    emit_int32(cond << 28 | 0xeb << 20 | single_cp_num |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   981
              fd->hi_bits() << 12 | fd->lo_bit() << 22 | (imm_8 & 0xf) | (imm_8 >> 4) << 16);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   982
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   983
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   984
  void fconstd(FloatRegister fd, unsigned char imm_8, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   985
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   986
    assert(fd->lo_bit() == 0, "double precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   987
    emit_int32(cond << 28 | 0xeb << 20 | double_cp_num |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   988
              fd->hi_bits() << 12 | fd->hi_bit() << 22 | (imm_8 & 0xf) | (imm_8 >> 4) << 16);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   989
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   990
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   991
  // GPR <-> FPR transfers
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   992
  void fmsr(FloatRegister fd, Register rd, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   993
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   994
    assert(fd->hi_bit() == 0, "double precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   995
    emit_int32(cond << 28 | 0xe0 << 20 | single_cp_num | 1 << 4 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   996
              fd->hi_bits() << 16 | fd->lo_bit() << 7 | rd->encoding() << 12);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   997
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   998
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   999
  void fmrs(Register rd, FloatRegister fd, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1000
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1001
    assert(fd->hi_bit() == 0, "double precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1002
    emit_int32(cond << 28 | 0xe1 << 20 | single_cp_num | 1 << 4 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1003
              fd->hi_bits() << 16 | fd->lo_bit() << 7 | rd->encoding() << 12);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1004
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1005
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1006
  void fmdrr(FloatRegister fd, Register rd, Register rn, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1007
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1008
    assert(fd->lo_bit() == 0, "single precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1009
    emit_int32(cond << 28 | 0xc4 << 20 | double_cp_num | 1 << 4 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1010
              fd->hi_bits() | fd->hi_bit() << 5 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1011
              rn->encoding() << 16 | rd->encoding() << 12);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1012
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1013
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1014
  void fmrrd(Register rd, Register rn, FloatRegister fd, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1015
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1016
    assert(fd->lo_bit() == 0, "single precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1017
    emit_int32(cond << 28 | 0xc5 << 20 | double_cp_num | 1 << 4 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1018
              fd->hi_bits() | fd->hi_bit() << 5 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1019
              rn->encoding() << 16 | rd->encoding() << 12);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1020
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1021
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1022
  void fmstat(AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1023
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1024
    emit_int32(cond << 28 | 0xef1fa10);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1025
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1026
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1027
  void vmrs(Register rt, VFPSystemRegister sr, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1028
    assert((sr->encoding() & (~0xf)) == 0, "what system register is that?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1029
    emit_int32(cond << 28 | rt->encoding() << 12 | sr->encoding() << 16 | 0xef00a10);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1030
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1031
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1032
  void vmsr(VFPSystemRegister sr, Register rt, AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1033
    assert((sr->encoding() & (~0xf)) == 0, "what system register is that?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1034
    emit_int32(cond << 28 | rt->encoding() << 12 | sr->encoding() << 16 | 0xee00a10);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1035
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1036
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1037
  void vcnt(FloatRegister Dd, FloatRegister Dm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1038
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1039
    // emitted at VM startup to detect whether the instruction is available
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1040
    assert(!VM_Version::is_initialized() || VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1041
    assert(Dd->lo_bit() == 0 && Dm->lo_bit() == 0, "single precision registers?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1042
    emit_int32(0xf3b00500 | Dd->hi_bit() << 22 | Dd->hi_bits() << 12 | Dm->hi_bit() << 5 | Dm->hi_bits());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1043
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1044
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1045
  void vpaddl(FloatRegister Dd, FloatRegister Dm, int size, bool s) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1046
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1047
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1048
    assert(Dd->lo_bit() == 0 && Dm->lo_bit() == 0, "single precision registers?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1049
    assert(size == 8 || size == 16 || size == 32, "unexpected size");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1050
    emit_int32(0xf3b00200 | Dd->hi_bit() << 22 | (size >> 4) << 18 | Dd->hi_bits() << 12 | (s ? 0 : 1) << 7 | Dm->hi_bit() << 5 | Dm->hi_bits());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1051
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1052
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1053
  void vld1(FloatRegister Dd, Address addr, VElem_Size size, int bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1054
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1055
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1056
    assert(Dd->lo_bit() == 0, "single precision registers?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1057
    int align = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1058
    assert(bits == 128, "code assumption");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1059
    VLD_Type type = VLD1_TYPE_2_REGS; // 2x64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1060
    emit_int32(0xf4200000 | Dd->hi_bit() << 22 | Dd->hi_bits() << 12 | type << 8 | size << 6 | align << 4 | addr.encoding_simd());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1061
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1062
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1063
  void vst1(FloatRegister Dd, Address addr, VElem_Size size, int bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1064
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1065
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1066
    assert(Dd->lo_bit() == 0, "single precision registers?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1067
    int align = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1068
    assert(bits == 128, "code assumption");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1069
    VLD_Type type = VLD1_TYPE_2_REGS; // 2x64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1070
    emit_int32(0xf4000000 | Dd->hi_bit() << 22 | Dd->hi_bits() << 12 | type << 8 | size << 6 | align << 4 | addr.encoding_simd());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1071
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1072
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1073
  void vmovI(FloatRegister Dd, int imm8, VElem_Size size, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1074
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1075
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1076
    assert(Dd->lo_bit() == 0, "single precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1077
    assert(!quad || (Dd->hi_bits() & 1) == 0, "quad precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1078
    assert(imm8 >= 0 && imm8 < 256, "out of range");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1079
    int op;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1080
    int cmode;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1081
    switch (size) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1082
    case VELEM_SIZE_8:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1083
      op = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1084
      cmode = 0xE /* 0b1110 */;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1085
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1086
    case VELEM_SIZE_16:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1087
      op = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1088
      cmode = 0x8 /* 0b1000 */;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1089
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1090
    case VELEM_SIZE_32:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1091
      op = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1092
      cmode = 0x0 /* 0b0000 */;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1093
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1094
    default:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1095
      ShouldNotReachHere();
51381
e354938b4073 8209380: ARM: cleanup maybe-uninitialized and reorder compiler warnings
avoitylov
parents: 49364
diff changeset
  1096
      return;
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1097
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1098
    emit_int32(0xf << 28 | 0x1 << 25 | 0x1 << 23 | 0x1 << 4 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1099
              (imm8 >> 7) << 24 | ((imm8 & 0x70) >> 4) << 16 | (imm8 & 0xf) |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1100
              quad << 6 | op << 5 | cmode << 8 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1101
              Dd->hi_bits() << 12 | Dd->hi_bit() << 22);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1102
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1103
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1104
  void vdupI(FloatRegister Dd, Register Rs, VElem_Size size, int quad,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1105
             AsmCondition cond = al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1106
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1107
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1108
    assert(Dd->lo_bit() == 0, "single precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1109
    assert(!quad || (Dd->hi_bits() & 1) == 0, "quad precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1110
    int b;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1111
    int e;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1112
    switch (size) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1113
    case VELEM_SIZE_8:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1114
      b = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1115
      e = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1116
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1117
    case VELEM_SIZE_16:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1118
      b = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1119
      e = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1120
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1121
    case VELEM_SIZE_32:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1122
      b = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1123
      e = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1124
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1125
    default:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1126
      ShouldNotReachHere();
51381
e354938b4073 8209380: ARM: cleanup maybe-uninitialized and reorder compiler warnings
avoitylov
parents: 49364
diff changeset
  1127
      return;
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1128
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1129
    emit_int32(cond << 28 | 0x1D /* 0b11101 */ << 23 | 0xB /* 0b1011 */ << 8 | 0x1 << 4 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1130
              quad << 21 | b << 22 |  e << 5 | Rs->encoding() << 12 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1131
              Dd->hi_bits() << 16 | Dd->hi_bit() << 7);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1132
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1133
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1134
  void vdup(FloatRegister Dd, FloatRegister Ds, int index, int size, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1135
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1136
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1137
    assert(Dd->lo_bit() == 0, "single precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1138
    assert(Ds->lo_bit() == 0, "single precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1139
    assert(!quad || (Dd->hi_bits() & 1) == 0, "quad precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1140
    int range = 64 / size;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1141
    assert(index < range, "overflow");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1142
    int imm4;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1143
    switch (size) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1144
    case 8:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1145
      assert((index & 0x7 /* 0b111 */) == index, "overflow");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1146
      imm4 = index << 1 | 0x1 /* 0b0001 */;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1147
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1148
    case 16:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1149
      assert((index & 0x3 /* 0b11 */) == index, "overflow");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1150
      imm4 = index << 2 | 0x2 /* 0b0010 */;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1151
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1152
    case 32:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1153
      assert((index & 0x1 /* 0b1 */) == index, "overflow");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1154
      imm4 = index << 3 | 0x4 /* 0b0100 */;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1155
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1156
    default:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1157
      ShouldNotReachHere();
51381
e354938b4073 8209380: ARM: cleanup maybe-uninitialized and reorder compiler warnings
avoitylov
parents: 49364
diff changeset
  1158
      return;
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1159
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1160
    emit_int32(0xF /* 0b1111 */ << 28 | 0x3B /* 0b00111011 */ << 20 | 0x6 /* 0b110 */ << 9 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1161
               quad << 6 | imm4 << 16 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1162
               Dd->hi_bits() << 12 | Dd->hi_bit() << 22 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1163
               Ds->hi_bits() << 00 | Ds->hi_bit() << 5);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1164
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1165
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1166
  void vdupF(FloatRegister Dd, FloatRegister Ss, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1167
    int index = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1168
    FloatRegister Ds = as_FloatRegister(Ss->encoding() & ~1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1169
    if (Ss->lo_bit() != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1170
      /* odd S register */
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1171
      assert(Ds->successor() == Ss, "bad reg");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1172
      index = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1173
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1174
      /* even S register */
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1175
      assert(Ds == Ss, "bad reg");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1176
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1177
    vdup(Dd, Ds, index, 32, quad);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1178
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1179
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1180
  void vrev(FloatRegister Dd, FloatRegister Dm, int quad, int region_size, VElem_Size size) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1181
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1182
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1183
    assert(Dd->lo_bit() == 0, "single precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1184
    assert(Dm->lo_bit() == 0, "single precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1185
    assert(!quad || ((Dd->hi_bits() | Dm->hi_bits()) & 1) == 0,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1186
           "quad precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1187
    unsigned int op = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1188
    switch (region_size) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1189
      case 16: op = 0x2; /*0b10*/ break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1190
      case 32: op = 0x1; /*0b01*/ break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1191
      case 64: op = 0x0; /*0b00*/ break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1192
      default: assert(false, "encoding constraint");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1193
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1194
    emit_int32(0xf << 28 | 0x7 << 23 | Dd->hi_bit() << 22 | 0x3 << 20 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1195
               size << 18 | Dd->hi_bits() << 12 | op  << 7 | quad << 6 | Dm->hi_bit() << 5 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1196
               Dm->hi_bits());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1197
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1198
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1199
  void veor(FloatRegister Dd, FloatRegister Dn, FloatRegister Dm, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1200
    CHECK_VFP_PRESENT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1201
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1202
    assert(Dd->lo_bit() == 0, "single precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1203
    assert(Dm->lo_bit() == 0, "single precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1204
    assert(Dn->lo_bit() == 0, "single precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1205
    assert(!quad || ((Dd->hi_bits() | Dm->hi_bits() | Dn->hi_bits()) & 1) == 0,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1206
           "quad precision register?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1207
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1208
    emit_int32(0xf << 28 | 0x3 << 24 | Dd->hi_bit() << 22 | Dn->hi_bits() << 16 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1209
               Dd->hi_bits() << 12 | 0x1 << 8 | Dn->hi_bit() << 7 | quad << 6 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1210
               Dm->hi_bit() << 5 | 0x1 << 4 | Dm->hi_bits());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1211
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1212
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1213
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1214
  Assembler(CodeBuffer* code) : AbstractAssembler(code) {}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1215
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1216
#ifdef COMPILER2
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1217
  typedef VFP::double_num double_num;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1218
  typedef VFP::float_num  float_num;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1219
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1220
};
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1221
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1222
#ifdef __SOFTFP__
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1223
// Soft float function declarations
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1224
extern "C" {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1225
extern float  __aeabi_fadd(float, float);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1226
extern float  __aeabi_fmul(float, float);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1227
extern float  __aeabi_fsub(float, float);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1228
extern float  __aeabi_fdiv(float, float);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1229
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1230
extern double __aeabi_dadd(double, double);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1231
extern double __aeabi_dmul(double, double);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1232
extern double __aeabi_dsub(double, double);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1233
extern double __aeabi_ddiv(double, double);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1234
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1235
extern double __aeabi_f2d(float);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1236
extern float  __aeabi_d2f(double);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1237
extern float  __aeabi_i2f(int);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1238
extern double __aeabi_i2d(int);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1239
extern int    __aeabi_f2iz(float);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1240
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1241
extern int  __aeabi_fcmpeq(float, float);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1242
extern int  __aeabi_fcmplt(float, float);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1243
extern int  __aeabi_fcmple(float, float);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1244
extern int  __aeabi_fcmpge(float, float);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1245
extern int  __aeabi_fcmpgt(float, float);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1246
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1247
extern int  __aeabi_dcmpeq(double, double);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1248
extern int  __aeabi_dcmplt(double, double);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1249
extern int  __aeabi_dcmple(double, double);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1250
extern int  __aeabi_dcmpge(double, double);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1251
extern int  __aeabi_dcmpgt(double, double);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1252
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1253
// Imported code from glibc soft-fp bundle for
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1254
// calculation accuracy improvement. See CR 6757269.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1255
extern double __aeabi_fadd_glibc(float, float);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1256
extern double __aeabi_fsub_glibc(float, float);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1257
extern double __aeabi_dadd_glibc(double, double);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1258
extern double __aeabi_dsub_glibc(double, double);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1259
};
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1260
#endif // __SOFTFP__
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1261
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1262
53244
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 52513
diff changeset
  1263
#endif // CPU_ARM_ASSEMBLER_ARM_32_HPP