hotspot/src/cpu/arm/vm/assembler_arm_64.hpp
author bobv
Mon, 19 Dec 2016 12:39:01 -0500
changeset 42664 29142a56c193
child 46525 3a5c833a43de
permissions -rw-r--r--
8168503: JEP 297: Unified arm32/arm64 Port Reviewed-by: kvn, enevill, ihse, dholmes, erikj, coleenp, cjplummer
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     1
/*
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     2
 * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    25
#ifndef CPU_ARM_VM_ASSEMBLER_ARM_64_HPP
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    26
#define CPU_ARM_VM_ASSEMBLER_ARM_64_HPP
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
enum AsmShift12 {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    29
  lsl0, lsl12
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    30
};
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    31
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    32
enum AsmPrefetchOp {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    33
    pldl1keep = 0b00000,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    34
    pldl1strm,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    35
    pldl2keep,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    36
    pldl2strm,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    37
    pldl3keep,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    38
    pldl3strm,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    39
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    40
    plil1keep = 0b01000,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    41
    plil1strm,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    42
    plil2keep,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    43
    plil2strm,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    44
    plil3keep,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    45
    plil3strm,
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
    pstl1keep = 0b10000,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    48
    pstl1strm,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    49
    pstl2keep,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    50
    pstl2strm,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    51
    pstl3keep,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    52
    pstl3strm,
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    55
// Shifted register operand for data processing instructions.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    56
class AsmOperand VALUE_OBJ_CLASS_SPEC {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    57
 private:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    58
  Register _reg;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    59
  AsmShift _shift;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    60
  int _shift_imm;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    61
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    62
 public:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    63
  AsmOperand(Register reg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    64
    assert(reg != SP, "SP is not allowed in shifted register operand");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    65
    _reg = reg;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    66
    _shift = lsl;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    67
    _shift_imm = 0;
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    70
  AsmOperand(Register reg, AsmShift shift, int shift_imm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    71
    assert(reg != SP, "SP is not allowed in shifted register operand");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    72
    assert(shift_imm >= 0, "shift amount should be non-negative");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    73
    _reg = reg;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    74
    _shift = shift;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    75
    _shift_imm = shift_imm;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    76
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    77
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    78
  Register reg() const {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    79
    return _reg;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    80
  }
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
  AsmShift shift() const {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    83
    return _shift;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    84
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    85
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    86
  int shift_imm() const {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    87
    return _shift_imm;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    88
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    89
};
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
class Assembler : public AbstractAssembler  {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    93
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    94
 public:
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
  static const int LogInstructionSize = 2;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    97
  static const int InstructionSize    = 1 << LogInstructionSize;
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
  Assembler(CodeBuffer* code) : AbstractAssembler(code) {}
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
  static inline AsmCondition inverse(AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   102
    assert ((cond != al) && (cond != nv), "AL and NV conditions cannot be inversed");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   103
    return (AsmCondition)((int)cond ^ 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   104
  }
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
  // Returns value of nzcv flags conforming to the given condition.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   107
  static inline int flags_for_condition(AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   108
    switch(cond) {            // NZCV
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   109
      case mi: case lt: return 0b1000;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   110
      case eq: case le: return 0b0100;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   111
      case hs: case hi: return 0b0010;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   112
      case vs:          return 0b0001;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   113
      default:          return 0b0000;
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   117
  // Immediate, encoded into logical instructions.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   118
  class LogicalImmediate {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   119
   private:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   120
    bool _encoded;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   121
    bool _is32bit;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   122
    int _immN;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   123
    int _immr;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   124
    int _imms;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   125
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   126
    static inline bool has_equal_subpatterns(uintx imm, int size);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   127
    static inline int least_pattern_size(uintx imm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   128
    static inline int population_count(uintx x);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   129
    static inline uintx set_least_zeroes(uintx x);
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
#ifdef ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   132
    uintx decode();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   133
#endif
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
    void construct(uintx imm, bool is32);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   136
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   137
   public:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   138
    LogicalImmediate(uintx imm, bool is32 = false) { construct(imm, is32); }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   139
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   140
    // Returns true if given immediate can be used in AArch64 logical instruction.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   141
    bool is_encoded() const { return _encoded; }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   142
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   143
    bool is32bit() const { return _is32bit; }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   144
    int immN() const { assert(_encoded, "should be"); return _immN; }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   145
    int immr() const { assert(_encoded, "should be"); return _immr; }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   146
    int imms() const { assert(_encoded, "should be"); return _imms; }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   147
  };
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
  // Immediate, encoded into arithmetic add/sub instructions.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   150
  class ArithmeticImmediate {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   151
   private:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   152
    bool _encoded;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   153
    int _imm;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   154
    AsmShift12 _shift;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   155
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   156
   public:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   157
    ArithmeticImmediate(intx x) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   158
      if (is_unsigned_imm_in_range(x, 12, 0)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   159
        _encoded = true;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   160
        _imm = x;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   161
        _shift = lsl0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   162
      } else if (is_unsigned_imm_in_range(x, 12, 12)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   163
        _encoded = true;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   164
        _imm = x >> 12;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   165
        _shift = lsl12;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   166
      } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   167
        _encoded = false;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   168
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   169
    }
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
    ArithmeticImmediate(intx x, AsmShift12 sh) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   172
      if (is_unsigned_imm_in_range(x, 12, 0)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   173
        _encoded = true;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   174
        _imm = x;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   175
        _shift = sh;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   176
      } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   177
        _encoded = false;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   178
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   179
    }
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
    // Returns true if this immediate can be used in AArch64 arithmetic (add/sub/cmp/cmn) instructions.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   182
    bool is_encoded() const  { return _encoded; }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   183
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   184
    int imm() const          { assert(_encoded, "should be"); return _imm; }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   185
    AsmShift12 shift() const { assert(_encoded, "should be"); return _shift; }
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   188
  static inline bool is_imm_in_range(intx value, int bits, int align_bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   189
    intx sign_bits = (value >> (bits + align_bits - 1));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   190
    return ((value & right_n_bits(align_bits)) == 0) && ((sign_bits == 0) || (sign_bits == -1));
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
  static inline int encode_imm(intx value, int bits, int align_bits, int low_bit_in_encoding) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   194
    assert (is_imm_in_range(value, bits, align_bits), "immediate value is out of range");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   195
    return ((value >> align_bits) & right_n_bits(bits)) << low_bit_in_encoding;
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   198
  static inline bool is_unsigned_imm_in_range(intx value, int bits, int align_bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   199
    return (value >= 0) && ((value & right_n_bits(align_bits)) == 0) && ((value >> (align_bits + bits)) == 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   200
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   201
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   202
  static inline int encode_unsigned_imm(intx value, int bits, int align_bits, int low_bit_in_encoding) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   203
    assert (is_unsigned_imm_in_range(value, bits, align_bits), "immediate value is out of range");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   204
    return (value >> align_bits) << low_bit_in_encoding;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   205
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   206
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   207
  static inline bool is_offset_in_range(intx offset, int bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   208
    assert (bits == 14 || bits == 19 || bits == 26, "wrong bits number");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   209
    return is_imm_in_range(offset, bits, 2);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   210
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   211
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   212
  static inline int encode_offset(intx offset, int bits, int low_bit_in_encoding) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   213
    return encode_imm(offset, bits, 2, low_bit_in_encoding);
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   216
  // 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
   217
  static inline bool is_arith_imm_in_range(intx value) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   218
    return ArithmeticImmediate(value).is_encoded();
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
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
  // Load/store instructions
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   223
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   224
#define F(mnemonic, opc) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   225
  void mnemonic(Register rd, address literal_addr) {                                                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   226
    intx offset = literal_addr - pc();                                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   227
    assert (opc != 0b01 || offset == 0 || ((uintx)literal_addr & 7) == 0, "ldr target should be aligned"); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   228
    assert (is_offset_in_range(offset, 19), "offset is out of range");                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   229
    emit_int32(opc << 30 | 0b011 << 27 | encode_offset(offset, 19, 5) | rd->encoding_with_zr());           \
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(ldr_w, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   233
  F(ldr,   0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   234
  F(ldrsw, 0b10)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   235
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   236
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   237
#define F(mnemonic, opc) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   238
  void mnemonic(FloatRegister rt, address literal_addr) {                                                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   239
    intx offset = literal_addr - pc();                                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   240
    assert (offset == 0 || ((uintx)literal_addr & right_n_bits(2 + opc)) == 0, "ldr target should be aligned"); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   241
    assert (is_offset_in_range(offset, 19), "offset is out of range");                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   242
    emit_int32(opc << 30 | 0b011100 << 24 | encode_offset(offset, 19, 5) | rt->encoding());                \
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   245
  F(ldr_s, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   246
  F(ldr_d, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   247
  F(ldr_q, 0b10)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   248
#undef F
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
#define F(mnemonic, size, o2, L, o1, o0) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   251
  void mnemonic(Register rt, Register rn) {                                                                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   252
    emit_int32(size << 30 | 0b001000 << 24 | o2 << 23 | L << 22 | o1 << 21 | 0b11111 << 16 |               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   253
        o0 << 15 | 0b11111 << 10 | rn->encoding_with_sp() << 5 | rt->encoding_with_zr());                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   254
  }
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
  F(ldxrb,   0b00, 0, 1, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   257
  F(ldaxrb,  0b00, 0, 1, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   258
  F(ldarb,   0b00, 1, 1, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   259
  F(ldxrh,   0b01, 0, 1, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   260
  F(ldaxrh,  0b01, 0, 1, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   261
  F(ldarh,   0b01, 1, 1, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   262
  F(ldxr_w,  0b10, 0, 1, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   263
  F(ldaxr_w, 0b10, 0, 1, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   264
  F(ldar_w,  0b10, 1, 1, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   265
  F(ldxr,    0b11, 0, 1, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   266
  F(ldaxr,   0b11, 0, 1, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   267
  F(ldar,    0b11, 1, 1, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   268
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   269
  F(stlrb,   0b00, 1, 0, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   270
  F(stlrh,   0b01, 1, 0, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   271
  F(stlr_w,  0b10, 1, 0, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   272
  F(stlr,    0b11, 1, 0, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   273
#undef F
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
#define F(mnemonic, size, o2, L, o1, o0) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   276
  void mnemonic(Register rs, Register rt, Register rn) {                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   277
    assert (rs != rt, "should be different");                                                                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   278
    assert (rs != rn, "should be different");                                                                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   279
    emit_int32(size << 30 | 0b001000 << 24 | o2 << 23 | L << 22 | o1 << 21 | rs->encoding_with_zr() << 16 |  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   280
        o0 << 15 | 0b11111 << 10 | rn->encoding_with_sp() << 5 | rt->encoding_with_zr());                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   281
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   282
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   283
  F(stxrb,   0b00, 0, 0, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   284
  F(stlxrb,  0b00, 0, 0, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   285
  F(stxrh,   0b01, 0, 0, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   286
  F(stlxrh,  0b01, 0, 0, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   287
  F(stxr_w,  0b10, 0, 0, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   288
  F(stlxr_w, 0b10, 0, 0, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   289
  F(stxr,    0b11, 0, 0, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   290
  F(stlxr,   0b11, 0, 0, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   291
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   292
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   293
#define F(mnemonic, size, o2, L, o1, o0) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   294
  void mnemonic(Register rt, Register rt2, Register rn) {                                                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   295
    assert (rt != rt2, "should be different");                                                             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   296
    emit_int32(size << 30 | 0b001000 << 24 | o2 << 23 | L << 22 | o1 << 21 | 0b11111 << 16 |               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   297
        o0 << 15 | rt2->encoding_with_zr() << 10 | rn->encoding_with_sp() << 5 | rt->encoding_with_zr());  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   298
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   299
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   300
  F(ldxp_w,  0b10, 0, 1, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   301
  F(ldaxp_w, 0b10, 0, 1, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   302
  F(ldxp,    0b11, 0, 1, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   303
  F(ldaxp,   0b11, 0, 1, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   304
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   305
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   306
#define F(mnemonic, size, o2, L, o1, o0) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   307
  void mnemonic(Register rs, Register rt, Register rt2, Register rn) {                                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   308
    assert (rs != rt, "should be different");                                                                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   309
    assert (rs != rt2, "should be different");                                                               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   310
    assert (rs != rn, "should be different");                                                                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   311
    emit_int32(size << 30 | 0b001000 << 24 | o2 << 23 | L << 22 | o1 << 21 | rs->encoding_with_zr() << 16 |  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   312
        o0 << 15 | rt2->encoding_with_zr() << 10 | rn->encoding_with_sp() << 5 | rt->encoding_with_zr());    \
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   315
  F(stxp_w,  0b10, 0, 0, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   316
  F(stlxp_w, 0b10, 0, 0, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   317
  F(stxp,    0b11, 0, 0, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   318
  F(stlxp,   0b11, 0, 0, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   319
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   320
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   321
#define F(mnemonic, opc, V, L) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   322
  void mnemonic(Register rt, Register rt2, Register rn, int offset = 0) {                                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   323
    assert (!L || rt != rt2, "should be different");                                                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   324
    int align_bits = 2 + (opc >> 1);                                                                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   325
    assert (is_imm_in_range(offset, 7, align_bits), "offset is out of range");                             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   326
    emit_int32(opc << 30 | 0b101 << 27 | V << 26 | L << 22 | encode_imm(offset, 7, align_bits, 15) |       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   327
        rt2->encoding_with_zr() << 10 | rn->encoding_with_sp() << 5 | rt->encoding_with_zr());             \
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   330
  F(stnp_w,  0b00, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   331
  F(ldnp_w,  0b00, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   332
  F(stnp,    0b10, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   333
  F(ldnp,    0b10, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   334
#undef F
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
#define F(mnemonic, opc, V, L) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   337
  void mnemonic(FloatRegister rt, FloatRegister rt2, Register rn, int offset = 0) {                        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   338
    assert (!L || (rt != rt2), "should be different");                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   339
    int align_bits = 2 + opc;                                                                              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   340
    assert (is_imm_in_range(offset, 7, align_bits), "offset is out of range");                             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   341
    emit_int32(opc << 30 | 0b101 << 27 | V << 26 | L << 22 | encode_imm(offset, 7, align_bits, 15) |       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   342
        rt2->encoding() << 10 | rn->encoding_with_sp() << 5 | rt->encoding());                             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   343
  }
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
  F(stnp_s,  0b00, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   346
  F(stnp_d,  0b01, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   347
  F(stnp_q,  0b10, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   348
  F(ldnp_s,  0b00, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   349
  F(ldnp_d,  0b01, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   350
  F(ldnp_q,  0b10, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   351
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   352
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   353
#define F(mnemonic, size, V, opc) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   354
  void mnemonic(Register rt, Address addr) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   355
    assert((addr.mode() == basic_offset) || (rt != addr.base()), "should be different");                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   356
    if (addr.index() == noreg) {                                                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   357
      if ((addr.mode() == basic_offset) && is_unsigned_imm_in_range(addr.disp(), 12, size)) {               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   358
        emit_int32(size << 30 | 0b111 << 27 | V << 26 | 0b01 << 24 | opc << 22 |                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   359
           encode_unsigned_imm(addr.disp(), 12, size, 10) |                                                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   360
           addr.base()->encoding_with_sp() << 5 | rt->encoding_with_zr());                                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   361
      } else {                                                                                              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   362
        assert(is_imm_in_range(addr.disp(), 9, 0), "offset is out of range");                               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   363
        emit_int32(size << 30 | 0b111 << 27 | V << 26 | opc << 22 | encode_imm(addr.disp(), 9, 0, 12) |     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   364
           addr.mode() << 10 | addr.base()->encoding_with_sp() << 5 | rt->encoding_with_zr());              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   365
      }                                                                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   366
    } else {                                                                                                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   367
      assert (addr.disp() == 0, "non-zero displacement for [reg + reg] address mode");                      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   368
      assert ((addr.shift_imm() == 0) || (addr.shift_imm() == size), "invalid shift amount");               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   369
      emit_int32(size << 30 | 0b111 << 27 | V << 26 | opc << 22 | 1 << 21 |                                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   370
         addr.index()->encoding_with_zr() << 16 | addr.extend() << 13 | (addr.shift_imm() != 0) << 12 |     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   371
         0b10 << 10 | addr.base()->encoding_with_sp() << 5 | rt->encoding_with_zr());                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   372
    }                                                                                                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   373
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   374
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   375
  F(strb,    0b00, 0, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   376
  F(ldrb,    0b00, 0, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   377
  F(ldrsb,   0b00, 0, 0b10)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   378
  F(ldrsb_w, 0b00, 0, 0b11)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   379
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   380
  F(strh,    0b01, 0, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   381
  F(ldrh,    0b01, 0, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   382
  F(ldrsh,   0b01, 0, 0b10)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   383
  F(ldrsh_w, 0b01, 0, 0b11)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   384
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   385
  F(str_w,   0b10, 0, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   386
  F(ldr_w,   0b10, 0, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   387
  F(ldrsw,   0b10, 0, 0b10)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   388
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   389
  F(str,     0b11, 0, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   390
  F(ldr,     0b11, 0, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   391
#undef F
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
#define F(mnemonic, size, V, opc) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   394
  void mnemonic(AsmPrefetchOp prfop, Address addr) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   395
    assert (addr.mode() == basic_offset, #mnemonic " supports only basic_offset address mode");             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   396
    if (addr.index() == noreg) {                                                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   397
      if (is_unsigned_imm_in_range(addr.disp(), 12, size)) {                                                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   398
        emit_int32(size << 30 | 0b111 << 27 | V << 26 | 0b01 << 24 | opc << 22 |                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   399
           encode_unsigned_imm(addr.disp(), 12, size, 10) |                                                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   400
           addr.base()->encoding_with_sp() << 5 | prfop);                                                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   401
      } else {                                                                                              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   402
        assert(is_imm_in_range(addr.disp(), 9, 0), "offset is out of range");                               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   403
        emit_int32(size << 30 | 0b111 << 27 | V << 26 | opc << 22 | encode_imm(addr.disp(), 9, 0, 12) |     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   404
           addr.base()->encoding_with_sp() << 5 | prfop);                                                   \
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
    } else {                                                                                                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   407
      assert (addr.disp() == 0, "non-zero displacement for [reg + reg] address mode");                      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   408
      assert ((addr.shift_imm() == 0) || (addr.shift_imm() == size), "invalid shift amount");               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   409
      emit_int32(size << 30 | 0b111 << 27 | V << 26 | opc << 22 | 1 << 21 |                                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   410
         addr.index()->encoding_with_zr() << 16 | addr.extend() << 13 | (addr.shift_imm() != 0) << 12 |     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   411
         0b10 << 10 | addr.base()->encoding_with_sp() << 5 | prfop);                                        \
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   415
  F(prfm, 0b11, 0, 0b10)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   416
#undef F
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
#define F(mnemonic, size, V, opc) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   419
  void mnemonic(FloatRegister rt, Address addr) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   420
    int align_bits = (((opc & 0b10) >> 1) << 2) | size;                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   421
    if (addr.index() == noreg) {                                                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   422
      if ((addr.mode() == basic_offset) && is_unsigned_imm_in_range(addr.disp(), 12, align_bits)) {         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   423
        emit_int32(size << 30 | 0b111 << 27 | V << 26 | 0b01 << 24 | opc << 22 |                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   424
           encode_unsigned_imm(addr.disp(), 12, align_bits, 10) |                                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   425
           addr.base()->encoding_with_sp() << 5 | rt->encoding());                                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   426
      } else {                                                                                              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   427
        assert(is_imm_in_range(addr.disp(), 9, 0), "offset is out of range");                               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   428
        emit_int32(size << 30 | 0b111 << 27 | V << 26 | opc << 22 | encode_imm(addr.disp(), 9, 0, 12) |     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   429
           addr.mode() << 10 | addr.base()->encoding_with_sp() << 5 | rt->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
    } else {                                                                                                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   432
      assert (addr.disp() == 0, "non-zero displacement for [reg + reg] address mode");                      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   433
      assert ((addr.shift_imm() == 0) || (addr.shift_imm() == align_bits), "invalid shift amount");         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   434
      emit_int32(size << 30 | 0b111 << 27 | V << 26 | opc << 22 | 1 << 21 |                                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   435
         addr.index()->encoding_with_zr() << 16 | addr.extend() << 13 | (addr.shift_imm() != 0) << 12 |     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   436
         0b10 << 10 | addr.base()->encoding_with_sp() << 5 | rt->encoding());                               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   437
    }                                                                                                       \
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
  F(str_b, 0b00, 1, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   441
  F(ldr_b, 0b00, 1, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   442
  F(str_h, 0b01, 1, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   443
  F(ldr_h, 0b01, 1, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   444
  F(str_s, 0b10, 1, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   445
  F(ldr_s, 0b10, 1, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   446
  F(str_d, 0b11, 1, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   447
  F(ldr_d, 0b11, 1, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   448
  F(str_q, 0b00, 1, 0b10)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   449
  F(ldr_q, 0b00, 1, 0b11)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   450
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   451
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   452
#define F(mnemonic, opc, V, L) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   453
  void mnemonic(Register rt, Register rt2, Address addr) {                                                         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   454
    assert((addr.mode() == basic_offset) || ((rt != addr.base()) && (rt2 != addr.base())), "should be different"); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   455
    assert(!L || (rt != rt2), "should be different");                                                              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   456
    assert(addr.index() == noreg, "[reg + reg] address mode is not available for load/store pair");                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   457
    int align_bits = 2 + (opc >> 1);                                                                               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   458
    int mode_encoding = (addr.mode() == basic_offset) ? 0b10 : addr.mode();                                        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   459
    assert(is_imm_in_range(addr.disp(), 7, align_bits), "offset is out of range");                                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   460
    emit_int32(opc << 30 | 0b101 << 27 | V << 26 | mode_encoding << 23 | L << 22 |                                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   461
       encode_imm(addr.disp(), 7, align_bits, 15) | rt2->encoding_with_zr() << 10 |                                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   462
       addr.base()->encoding_with_sp() << 5 | rt->encoding_with_zr());                                             \
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   465
  F(stp_w, 0b00, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   466
  F(ldp_w, 0b00, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   467
  F(ldpsw, 0b01, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   468
  F(stp,   0b10, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   469
  F(ldp,   0b10, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   470
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   471
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   472
#define F(mnemonic, opc, V, L) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   473
  void mnemonic(FloatRegister rt, FloatRegister rt2, Address addr) {                                                         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   474
    assert(!L || (rt != rt2), "should be different");                                                              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   475
    assert(addr.index() == noreg, "[reg + reg] address mode is not available for load/store pair");                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   476
    int align_bits = 2 + opc;                                                                                      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   477
    int mode_encoding = (addr.mode() == basic_offset) ? 0b10 : addr.mode();                                        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   478
    assert(is_imm_in_range(addr.disp(), 7, align_bits), "offset is out of range");                                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   479
    emit_int32(opc << 30 | 0b101 << 27 | V << 26 | mode_encoding << 23 | L << 22 |                                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   480
       encode_imm(addr.disp(), 7, align_bits, 15) | rt2->encoding() << 10 |                                        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   481
       addr.base()->encoding_with_sp() << 5 | rt->encoding());                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   482
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   483
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   484
  F(stp_s, 0b00, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   485
  F(ldp_s, 0b00, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   486
  F(stp_d, 0b01, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   487
  F(ldp_d, 0b01, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   488
  F(stp_q, 0b10, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   489
  F(ldp_q, 0b10, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   490
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   491
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   492
  // Data processing instructions
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   493
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   494
#define F(mnemonic, sf, opc) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   495
  void mnemonic(Register rd, Register rn, const LogicalImmediate& imm) {                      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   496
    assert (imm.is_encoded(), "illegal immediate for logical instruction");                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   497
    assert (imm.is32bit() == (sf == 0), "immediate size does not match instruction size");    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   498
    emit_int32(sf << 31 | opc << 29 | 0b100100 << 23 | imm.immN() << 22 | imm.immr() << 16 |  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   499
        imm.imms() << 10 | rn->encoding_with_zr() << 5 |                                      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   500
        ((opc == 0b11) ? rd->encoding_with_zr() : rd->encoding_with_sp()));                   \
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
  void mnemonic(Register rd, Register rn, uintx imm) {                                        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   503
    LogicalImmediate limm(imm, (sf == 0));                                                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   504
    mnemonic(rd, rn, limm);                                                                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   505
  }                                                                                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   506
  void mnemonic(Register rd, Register rn, unsigned int imm) {                                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   507
    mnemonic(rd, rn, (uintx)imm);                                                             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   508
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   509
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   510
  F(andr_w, 0, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   511
  F(orr_w,  0, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   512
  F(eor_w,  0, 0b10)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   513
  F(ands_w, 0, 0b11)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   514
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   515
  F(andr, 1, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   516
  F(orr,  1, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   517
  F(eor,  1, 0b10)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   518
  F(ands, 1, 0b11)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   519
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   520
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   521
  void tst(Register rn, unsigned int imm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   522
    ands(ZR, rn, imm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   523
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   524
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   525
  void tst_w(Register rn, unsigned int imm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   526
    ands_w(ZR, rn, imm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   527
  }
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
#define F(mnemonic, sf, opc, N) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   530
  void mnemonic(Register rd, Register rn, AsmOperand operand) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   531
    assert (operand.shift_imm() >> (5 + sf) == 0, "shift amount is too large");          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   532
    emit_int32(sf << 31 | opc << 29 | 0b01010 << 24 | operand.shift() << 22 | N << 21 |  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   533
        operand.reg()->encoding_with_zr() << 16 | operand.shift_imm() << 10 |            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   534
        rn->encoding_with_zr() << 5 | rd->encoding_with_zr());                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   535
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   536
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   537
  F(andr_w, 0, 0b00, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   538
  F(bic_w,  0, 0b00, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   539
  F(orr_w,  0, 0b01, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   540
  F(orn_w,  0, 0b01, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   541
  F(eor_w,  0, 0b10, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   542
  F(eon_w,  0, 0b10, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   543
  F(ands_w, 0, 0b11, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   544
  F(bics_w, 0, 0b11, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   545
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   546
  F(andr, 1, 0b00, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   547
  F(bic,  1, 0b00, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   548
  F(orr,  1, 0b01, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   549
  F(orn,  1, 0b01, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   550
  F(eor,  1, 0b10, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   551
  F(eon,  1, 0b10, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   552
  F(ands, 1, 0b11, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   553
  F(bics, 1, 0b11, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   554
#undef F
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
  void tst(Register rn, AsmOperand operand) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   557
    ands(ZR, rn, operand);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   558
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   559
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   560
  void tst_w(Register rn, AsmOperand operand) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   561
    ands_w(ZR, rn, operand);
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
  void mvn(Register rd, AsmOperand operand) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   565
    orn(rd, ZR, operand);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   566
  }
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
  void mvn_w(Register rd, AsmOperand operand) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   569
    orn_w(rd, ZR, operand);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   570
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   571
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   572
#define F(mnemonic, sf, op, S) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   573
  void mnemonic(Register rd, Register rn, const ArithmeticImmediate& imm) {                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   574
    assert(imm.is_encoded(), "immediate is out of range");                                        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   575
    emit_int32(sf << 31 | op << 30 | S << 29 | 0b10001 << 24 | imm.shift() << 22 |                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   576
        imm.imm() << 10 | rn->encoding_with_sp() << 5 |                                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   577
        (S == 1 ? rd->encoding_with_zr() : rd->encoding_with_sp()));                              \
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
  void mnemonic(Register rd, Register rn, int imm) {                                              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   580
    mnemonic(rd, rn, ArithmeticImmediate(imm));                                                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   581
  }                                                                                               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   582
  void mnemonic(Register rd, Register rn, int imm, AsmShift12 shift) {                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   583
    mnemonic(rd, rn, ArithmeticImmediate(imm, shift));                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   584
  }                                                                                               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   585
  void mnemonic(Register rd, Register rn, Register rm, AsmExtendOp extend, int shift_imm = 0) {   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   586
    assert ((0 <= shift_imm) && (shift_imm <= 4), "shift amount is out of range");                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   587
    emit_int32(sf << 31 | op << 30 | S << 29 | 0b01011001 << 21 | rm->encoding_with_zr() << 16 |  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   588
        extend << 13 | shift_imm << 10 | rn->encoding_with_sp() << 5 |                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   589
        (S == 1 ? rd->encoding_with_zr() : rd->encoding_with_sp()));                              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   590
  }                                                                                               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   591
  void mnemonic(Register rd, Register rn, AsmOperand operand) {                                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   592
    assert (operand.shift() != ror, "illegal shift type");                                        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   593
    assert (operand.shift_imm() >> (5 + sf) == 0, "shift amount is too large");                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   594
    emit_int32(sf << 31 | op << 30 | S << 29 | 0b01011 << 24 | operand.shift() << 22 |            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   595
        operand.reg()->encoding_with_zr() << 16 | operand.shift_imm() << 10 |                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   596
        rn->encoding_with_zr() << 5 | rd->encoding_with_zr());                                    \
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   599
  F(add_w,  0, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   600
  F(adds_w, 0, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   601
  F(sub_w,  0, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   602
  F(subs_w, 0, 1, 1)
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
  F(add,    1, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   605
  F(adds,   1, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   606
  F(sub,    1, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   607
  F(subs,   1, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   608
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   609
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   610
  void mov(Register rd, Register rm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   611
    if ((rd == SP) || (rm == SP)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   612
      add(rd, rm, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   613
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   614
      orr(rd, ZR, rm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   615
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   616
  }
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
  void mov_w(Register rd, Register rm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   619
    if ((rd == SP) || (rm == SP)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   620
      add_w(rd, rm, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   621
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   622
      orr_w(rd, ZR, rm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   623
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   624
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   625
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   626
  void cmp(Register rn, int imm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   627
    subs(ZR, rn, imm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   628
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   629
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   630
  void cmp_w(Register rn, int imm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   631
    subs_w(ZR, rn, imm);
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   634
  void cmp(Register rn, Register rm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   635
    assert (rm != SP, "SP should not be used as the 2nd operand of cmp");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   636
    if (rn == SP) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   637
      subs(ZR, rn, rm, ex_uxtx);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   638
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   639
      subs(ZR, rn, rm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   640
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   641
  }
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
  void cmp_w(Register rn, Register rm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   644
    assert ((rn != SP) && (rm != SP), "SP should not be used in 32-bit cmp");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   645
    subs_w(ZR, rn, rm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   646
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   647
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   648
  void cmp(Register rn, AsmOperand operand) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   649
    assert (rn != SP, "SP is not allowed in cmp with shifted register (AsmOperand)");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   650
    subs(ZR, rn, operand);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   651
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   652
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   653
  void cmn(Register rn, int imm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   654
    adds(ZR, rn, imm);
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   657
  void cmn_w(Register rn, int imm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   658
    adds_w(ZR, rn, imm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   659
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   660
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   661
  void cmn(Register rn, Register rm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   662
    assert (rm != SP, "SP should not be used as the 2nd operand of cmp");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   663
    if (rn == SP) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   664
      adds(ZR, rn, rm, ex_uxtx);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   665
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   666
      adds(ZR, rn, rm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   667
    }
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
  void cmn_w(Register rn, Register rm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   671
    assert ((rn != SP) && (rm != SP), "SP should not be used in 32-bit cmp");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   672
    adds_w(ZR, rn, rm);
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   675
  void neg(Register rd, Register rm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   676
    sub(rd, ZR, rm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   677
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   678
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   679
  void neg_w(Register rd, Register rm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   680
    sub_w(rd, ZR, rm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   681
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   682
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   683
#define F(mnemonic, sf, op, S) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   684
  void mnemonic(Register rd, Register rn, Register rm) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   685
    emit_int32(sf << 31 | op << 30 | S << 29 | 0b11010000 << 21 | rm->encoding_with_zr() << 16 |   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   686
        rn->encoding_with_zr() << 5 | rd->encoding_with_zr());                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   687
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   688
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   689
  F(adc_w,  0, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   690
  F(adcs_w, 0, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   691
  F(sbc_w,  0, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   692
  F(sbcs_w, 0, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   693
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   694
  F(adc,    1, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   695
  F(adcs,   1, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   696
  F(sbc,    1, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   697
  F(sbcs,   1, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   698
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   699
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   700
#define F(mnemonic, sf, N) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   701
  void mnemonic(Register rd, Register rn, Register rm, int lsb) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   702
    assert ((lsb >> (5 + sf)) == 0, "illegal least significant bit position");        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   703
    emit_int32(sf << 31 | 0b100111 << 23 | N << 22 | rm->encoding_with_zr() << 16 |   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   704
        lsb << 10 | rn->encoding_with_zr() << 5 | rd->encoding_with_zr());            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   705
  }
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
  F(extr_w,  0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   708
  F(extr,    1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   709
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   710
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   711
#define F(mnemonic, sf, opc) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   712
  void mnemonic(Register rd, int imm, int shift) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   713
    assert ((imm >> 16) == 0, "immediate is out of range");                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   714
    assert (((shift & 0xf) == 0) && ((shift >> (5 + sf)) == 0), "invalid shift"); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   715
    emit_int32(sf << 31 | opc << 29 | 0b100101 << 23 | (shift >> 4) << 21 |       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   716
        imm << 5 | rd->encoding_with_zr());                                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   717
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   718
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   719
  F(movn_w,  0, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   720
  F(movz_w,  0, 0b10)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   721
  F(movk_w,  0, 0b11)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   722
  F(movn,    1, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   723
  F(movz,    1, 0b10)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   724
  F(movk,    1, 0b11)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   725
#undef F
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 mov(Register rd, int imm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   728
    assert ((imm >> 16) == 0, "immediate is out of range");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   729
    movz(rd, imm, 0);
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 mov_w(Register rd, int imm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   733
    assert ((imm >> 16) == 0, "immediate is out of range");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   734
    movz_w(rd, imm, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   735
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   736
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   737
#define F(mnemonic, sf, op, S) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   738
  void mnemonic(Register rn, int imm, int nzcv, AsmCondition cond) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   739
    assert ((imm >> 5) == 0, "immediate is out of range");                      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   740
    assert ((nzcv >> 4) == 0, "illegal nzcv");                                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   741
    emit_int32(sf << 31 | op << 30 | S << 29 | 0b11010010 << 21 | imm << 16 |   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   742
         cond << 12 | 1 << 11 | rn->encoding_with_zr() << 5 | nzcv);            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   743
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   744
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   745
  F(ccmn_w, 0, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   746
  F(ccmp_w, 0, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   747
  F(ccmn,   1, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   748
  F(ccmp,   1, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   749
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   750
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   751
#define F(mnemonic, sf, op, S) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   752
  void mnemonic(Register rn, Register rm, int nzcv, AsmCondition cond) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   753
    assert ((nzcv >> 4) == 0, "illegal nzcv");                                                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   754
    emit_int32(sf << 31 | op << 30 | S << 29 | 0b11010010 << 21 | rm->encoding_with_zr() << 16 |  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   755
        cond << 12 | rn->encoding_with_zr() << 5 | nzcv);                                         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   756
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   757
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   758
  F(ccmn_w, 0, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   759
  F(ccmp_w, 0, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   760
  F(ccmn,   1, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   761
  F(ccmp,   1, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   762
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   763
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   764
#define F(mnemonic, sf, op, S, op2) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   765
  void mnemonic(Register rd, Register rn, Register rm, AsmCondition cond) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   766
    emit_int32(sf << 31 | op << 30 | S << 29 | 0b11010100 << 21 | rm->encoding_with_zr() << 16 |  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   767
        cond << 12 | op2 << 10 | rn->encoding_with_zr() << 5 | rd->encoding_with_zr());           \
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   770
  F(csel_w,  0, 0, 0, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   771
  F(csinc_w, 0, 0, 0, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   772
  F(csinv_w, 0, 1, 0, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   773
  F(csneg_w, 0, 1, 0, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   774
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   775
  F(csel,    1, 0, 0, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   776
  F(csinc,   1, 0, 0, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   777
  F(csinv,   1, 1, 0, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   778
  F(csneg,   1, 1, 0, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   779
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   780
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   781
  void cset(Register rd, AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   782
    csinc(rd, ZR, ZR, inverse(cond));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   783
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   784
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   785
  void cset_w(Register rd, AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   786
    csinc_w(rd, ZR, ZR, inverse(cond));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   787
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   788
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   789
  void csetm(Register rd, AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   790
    csinv(rd, ZR, ZR, inverse(cond));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   791
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   792
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   793
  void csetm_w(Register rd, AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   794
    csinv_w(rd, ZR, ZR, inverse(cond));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   795
  }
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
  void cinc(Register rd, Register rn, AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   798
    csinc(rd, rn, rn, inverse(cond));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   799
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   800
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   801
  void cinc_w(Register rd, Register rn, AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   802
    csinc_w(rd, rn, rn, inverse(cond));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   803
  }
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 cinv(Register rd, Register rn, AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   806
    csinv(rd, rn, rn, inverse(cond));
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
  void cinv_w(Register rd, Register rn, AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   810
    csinv_w(rd, rn, rn, inverse(cond));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   811
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   812
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   813
#define F(mnemonic, sf, S, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   814
  void mnemonic(Register rd, Register rn) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   815
    emit_int32(sf << 31 | 1 << 30 | S << 29 | 0b11010110 << 21 | opcode << 10 |  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   816
        rn->encoding_with_zr() << 5 | rd->encoding_with_zr());                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   817
  }
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
  F(rbit_w,  0, 0, 0b000000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   820
  F(rev16_w, 0, 0, 0b000001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   821
  F(rev_w,   0, 0, 0b000010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   822
  F(clz_w,   0, 0, 0b000100)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   823
  F(cls_w,   0, 0, 0b000101)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   824
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   825
  F(rbit,    1, 0, 0b000000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   826
  F(rev16,   1, 0, 0b000001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   827
  F(rev32,   1, 0, 0b000010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   828
  F(rev,     1, 0, 0b000011)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   829
  F(clz,     1, 0, 0b000100)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   830
  F(cls,     1, 0, 0b000101)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   831
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   832
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   833
#define F(mnemonic, sf, S, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   834
  void mnemonic(Register rd, Register rn, Register rm) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   835
    emit_int32(sf << 31 | S << 29 | 0b11010110 << 21 | rm->encoding_with_zr() << 16 |  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   836
        opcode << 10 | rn->encoding_with_zr() << 5 | rd->encoding_with_zr());          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   837
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   838
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   839
  F(udiv_w,  0, 0, 0b000010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   840
  F(sdiv_w,  0, 0, 0b000011)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   841
  F(lslv_w,  0, 0, 0b001000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   842
  F(lsrv_w,  0, 0, 0b001001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   843
  F(asrv_w,  0, 0, 0b001010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   844
  F(rorv_w,  0, 0, 0b001011)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   845
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   846
  F(udiv,    1, 0, 0b000010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   847
  F(sdiv,    1, 0, 0b000011)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   848
  F(lslv,    1, 0, 0b001000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   849
  F(lsrv,    1, 0, 0b001001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   850
  F(asrv,    1, 0, 0b001010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   851
  F(rorv,    1, 0, 0b001011)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   852
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   853
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   854
#define F(mnemonic, sf, op31, o0) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   855
  void mnemonic(Register rd, Register rn, Register rm, Register ra) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   856
    emit_int32(sf << 31 | 0b11011 << 24 | op31 << 21 | rm->encoding_with_zr() << 16 |                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   857
        o0 << 15 | ra->encoding_with_zr() << 10 | rn->encoding_with_zr() << 5 | rd->encoding_with_zr());  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   858
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   859
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   860
  F(madd_w,  0, 0b000, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   861
  F(msub_w,  0, 0b000, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   862
  F(madd,    1, 0b000, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   863
  F(msub,    1, 0b000, 1)
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
  F(smaddl,  1, 0b001, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   866
  F(smsubl,  1, 0b001, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   867
  F(umaddl,  1, 0b101, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   868
  F(umsubl,  1, 0b101, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   869
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   870
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   871
  void mul(Register rd, Register rn, Register rm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   872
      madd(rd, rn, rm, ZR);
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   875
  void mul_w(Register rd, Register rn, Register rm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   876
      madd_w(rd, rn, rm, ZR);
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   879
#define F(mnemonic, sf, op31, o0) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   880
  void mnemonic(Register rd, Register rn, Register rm) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   881
    emit_int32(sf << 31 | 0b11011 << 24 | op31 << 21 | rm->encoding_with_zr() << 16 |      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   882
        o0 << 15 | 0b11111 << 10 | rn->encoding_with_zr() << 5 | rd->encoding_with_zr());  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   883
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   884
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   885
  F(smulh,   1, 0b010, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   886
  F(umulh,   1, 0b110, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   887
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   888
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   889
#define F(mnemonic, op) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   890
  void mnemonic(Register rd, address addr) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   891
    intx offset;                                                        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   892
    if (op == 0) {                                                      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   893
      offset = addr - pc();                                             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   894
    } else {                                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   895
      offset = (((intx)addr) - (((intx)pc()) & ~0xfff)) >> 12;          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   896
    }                                                                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   897
    assert (is_imm_in_range(offset, 21, 0), "offset is out of range");  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   898
    emit_int32(op << 31 | (offset & 3) << 29 | 0b10000 << 24 |          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   899
        encode_imm(offset >> 2, 19, 0, 5) | rd->encoding_with_zr());    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   900
  }                                                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   901
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   902
  F(adr,   0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   903
  F(adrp,  1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   904
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   905
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   906
  void adr(Register rd, Label& L) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   907
    adr(rd, target(L));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   908
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   909
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   910
#define F(mnemonic, sf, opc, N)                                                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   911
  void mnemonic(Register rd, Register rn, int immr, int imms) {                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   912
    assert ((immr >> (5 + sf)) == 0, "immr is out of range");                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   913
    assert ((imms >> (5 + sf)) == 0, "imms is out of range");                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   914
    emit_int32(sf << 31 | opc << 29 | 0b100110 << 23 | N << 22 | immr << 16 |  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   915
        imms << 10 | rn->encoding_with_zr() << 5 | rd->encoding_with_zr());    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   916
  }
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
  F(sbfm_w, 0, 0b00, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   919
  F(bfm_w,  0, 0b01, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   920
  F(ubfm_w, 0, 0b10, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   921
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   922
  F(sbfm, 1, 0b00, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   923
  F(bfm,  1, 0b01, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   924
  F(ubfm, 1, 0b10, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   925
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   926
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   927
#define F(alias, mnemonic, sf, immr, imms) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   928
  void alias(Register rd, Register rn, int lsb, int width) {                        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   929
    assert ((lsb >> (5 + sf)) == 0, "lsb is out of range");                         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   930
    assert ((1 <= width) && (width <= (32 << sf) - lsb), "width is out of range");  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   931
    mnemonic(rd, rn, immr, imms);                                                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   932
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   933
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   934
  F(bfi_w,   bfm_w,  0, (-lsb) & 0x1f, width - 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   935
  F(bfi,     bfm,    1, (-lsb) & 0x3f, width - 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   936
  F(bfxil_w, bfm_w,  0, lsb,           lsb + width - 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   937
  F(bfxil,   bfm,    1, lsb,           lsb + width - 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   938
  F(sbfiz_w, sbfm_w, 0, (-lsb) & 0x1f, width - 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   939
  F(sbfiz,   sbfm,   1, (-lsb) & 0x3f, width - 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   940
  F(sbfx_w,  sbfm_w, 0, lsb,           lsb + width - 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   941
  F(sbfx,    sbfm,   1, lsb,           lsb + width - 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   942
  F(ubfiz_w, ubfm_w, 0, (-lsb) & 0x1f, width - 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   943
  F(ubfiz,   ubfm,   1, (-lsb) & 0x3f, width - 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   944
  F(ubfx_w,  ubfm_w, 0, lsb,           lsb + width - 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   945
  F(ubfx,    ubfm,   1, lsb,           lsb + width - 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   946
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   947
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   948
#define F(alias, mnemonic, sf, immr, imms) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   949
  void alias(Register rd, Register rn, int shift) {              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   950
    assert ((shift >> (5 + sf)) == 0, "shift is out of range");  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   951
    mnemonic(rd, rn, immr, imms);                                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   952
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   953
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   954
  F(_asr_w, sbfm_w, 0, shift, 31)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   955
  F(_asr,   sbfm,   1, shift, 63)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   956
  F(_lsl_w, ubfm_w, 0, (-shift) & 0x1f, 31 - shift)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   957
  F(_lsl,   ubfm,   1, (-shift) & 0x3f, 63 - shift)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   958
  F(_lsr_w, ubfm_w, 0, shift, 31)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   959
  F(_lsr,   ubfm,   1, shift, 63)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   960
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   961
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   962
#define F(alias, mnemonic, immr, imms) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   963
  void alias(Register rd, Register rn) {   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   964
    mnemonic(rd, rn, immr, imms);          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   965
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   966
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   967
  F(sxtb_w, sbfm_w, 0, 7)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   968
  F(sxtb,   sbfm,   0, 7)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   969
  F(sxth_w, sbfm_w, 0, 15)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   970
  F(sxth,   sbfm,   0, 15)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   971
  F(sxtw,   sbfm,   0, 31)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   972
  F(uxtb_w, ubfm_w, 0, 7)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   973
  F(uxtb,   ubfm,   0, 7)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   974
  F(uxth_w, ubfm_w, 0, 15)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   975
  F(uxth,   ubfm,   0, 15)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   976
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   977
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   978
  // Branch instructions
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   979
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   980
#define F(mnemonic, op) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   981
  void mnemonic(Register rn) {                                                             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   982
    emit_int32(0b1101011 << 25 | op << 21 | 0b11111 << 16 | rn->encoding_with_zr() << 5);  \
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   985
  F(br,  0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   986
  F(blr, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   987
  F(ret, 0b10)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   988
#undef F
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
  void ret() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   991
    ret(LR);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   992
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   993
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   994
#define F(mnemonic, op) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   995
  void mnemonic(address target) {                                         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   996
    intx offset = target - pc();                                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   997
    assert (is_offset_in_range(offset, 26), "offset is out of range");    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   998
    emit_int32(op << 31 | 0b00101 << 26 | encode_offset(offset, 26, 0));  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   999
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1000
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1001
  F(b,  0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1002
  F(bl, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1003
#undef F
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
  void b(address target, AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1006
    if (cond == al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1007
      b(target);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1008
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1009
      intx offset = target - pc();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1010
      assert (is_offset_in_range(offset, 19), "offset is out of range");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1011
      emit_int32(0b0101010 << 25 | encode_offset(offset, 19, 5) | cond);
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1015
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1016
#define F(mnemonic, sf, op)                                             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1017
  void mnemonic(Register rt, address target) {                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1018
    intx offset = target - pc();                                        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1019
    assert (is_offset_in_range(offset, 19), "offset is out of range");  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1020
    emit_int32(sf << 31 | 0b011010 << 25 | op << 24 | encode_offset(offset, 19, 5) | rt->encoding_with_zr()); \
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1023
  F(cbz_w,  0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1024
  F(cbnz_w, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1025
  F(cbz,    1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1026
  F(cbnz,   1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1027
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1028
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1029
#define F(mnemonic, op)                                                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1030
  void mnemonic(Register rt, int bit, address target) {                 \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1031
    intx offset = target - pc();                                        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1032
    assert (is_offset_in_range(offset, 14), "offset is out of range");  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1033
    assert (0 <= bit && bit < 64, "bit number is out of range");        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1034
    emit_int32((bit >> 5) << 31 | 0b011011 << 25 | op << 24 | (bit & 0x1f) << 19 | \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1035
        encode_offset(offset, 14, 5) | rt->encoding_with_zr());         \
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1038
  F(tbz,  0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1039
  F(tbnz, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1040
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1041
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1042
  // System instructions
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
  enum DMB_Opt {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1045
    DMB_ld  = 0b1101,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1046
    DMB_st  = 0b1110,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1047
    DMB_all = 0b1111
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1048
  };
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1049
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1050
#define F(mnemonic, L, op0, op1, CRn, op2, Rt) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1051
  void mnemonic(DMB_Opt option) {                                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1052
    emit_int32(0b1101010100 << 22 | L << 21 | op0 << 19 | op1 << 16 |   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1053
        CRn << 12 | option << 8 | op2 << 5 | Rt);                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1054
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1055
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1056
  F(dsb,  0, 0b00, 0b011, 0b0011, 0b100, 0b11111)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1057
  F(dmb,  0, 0b00, 0b011, 0b0011, 0b101, 0b11111)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1058
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1059
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1060
#define F(mnemonic, L, op0, op1, CRn, Rt) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1061
  void mnemonic(int imm) {                                              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1062
    assert ((imm >> 7) == 0, "immediate is out of range");              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1063
    emit_int32(0b1101010100 << 22 | L << 21 | op0 << 19 | op1 << 16 |   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1064
        CRn << 12 | imm << 5 | Rt);                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1065
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1066
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1067
  F(hint, 0, 0b00, 0b011, 0b0010, 0b11111)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1068
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1069
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1070
  void nop() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1071
    hint(0);
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1074
  void yield() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1075
    hint(1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1076
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1077
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1078
#define F(mnemonic, opc, op2, LL) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1079
  void mnemonic(int imm = 0) {                                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1080
    assert ((imm >> 16) == 0, "immediate is out of range");              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1081
    emit_int32(0b11010100 << 24 | opc << 21 | imm << 5 | op2 << 2 | LL); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1082
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1083
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1084
  F(brk, 0b001, 0b000, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1085
  F(hlt, 0b010, 0b000, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1086
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1087
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1088
  enum SystemRegister { // o0<1> op1<3> CRn<4> CRm<4> op2<3>
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1089
    SysReg_NZCV = 0b101101000010000,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1090
    SysReg_FPCR = 0b101101000100000,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1091
  };
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1092
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1093
  void mrs(Register rt, SystemRegister systemReg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1094
    assert ((systemReg >> 15) == 0, "systemReg is out of range");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1095
    emit_int32(0b110101010011 << 20 | systemReg << 5 | rt->encoding_with_zr());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1096
  }
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
  void msr(SystemRegister systemReg, Register rt) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1099
    assert ((systemReg >> 15) == 0, "systemReg is out of range");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1100
    emit_int32(0b110101010001 << 20 | systemReg << 5 | rt->encoding_with_zr());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1101
  }
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
  // Floating-point instructions
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1104
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1105
#define F(mnemonic, M, S, type, opcode2) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1106
  void mnemonic(FloatRegister rn, FloatRegister rm) {                         \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1107
    emit_int32(M << 31 | S << 29 | 0b11110 << 24 | type << 22 | 1 << 21 |     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1108
        rm->encoding() << 16 | 0b1000 << 10 | rn->encoding() << 5 | opcode2); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1109
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1110
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1111
  F(fcmp_s,   0, 0, 0b00, 0b00000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1112
  F(fcmpe_s,  0, 0, 0b00, 0b01000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1113
  F(fcmp_d,   0, 0, 0b01, 0b00000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1114
  F(fcmpe_d,  0, 0, 0b01, 0b10000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1115
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1116
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1117
#define F(mnemonic, M, S, type, opcode2) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1118
  void mnemonic(FloatRegister rn) {                                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1119
    emit_int32(M << 31 | S << 29 | 0b11110 << 24 | type << 22 | 1 << 21 |     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1120
        0b1000 << 10 | rn->encoding() << 5 | opcode2);                        \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1121
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1122
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1123
  F(fcmp0_s,   0, 0, 0b00, 0b01000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1124
  F(fcmpe0_s,  0, 0, 0b00, 0b11000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1125
  F(fcmp0_d,   0, 0, 0b01, 0b01000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1126
  F(fcmpe0_d,  0, 0, 0b01, 0b11000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1127
#undef F
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
#define F(mnemonic, M, S, type, op) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1130
  void mnemonic(FloatRegister rn, FloatRegister rm, int nzcv, AsmCondition cond) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1131
    assert ((nzcv >> 4) == 0, "illegal nzcv");                                                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1132
    emit_int32(M << 31 | S << 29 | 0b11110 << 24 | type << 22 | 1 << 21 |                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1133
        rm->encoding() << 16 | cond << 12 | 0b01 << 10 | rn->encoding() << 5 | op << 4 | nzcv); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1134
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1135
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1136
  F(fccmp_s,   0, 0, 0b00, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1137
  F(fccmpe_s,  0, 0, 0b00, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1138
  F(fccmp_d,   0, 0, 0b01, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1139
  F(fccmpe_d,  0, 0, 0b01, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1140
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1141
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1142
#define F(mnemonic, M, S, type) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1143
  void mnemonic(FloatRegister rd, FloatRegister rn, FloatRegister rm, AsmCondition cond) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1144
    emit_int32(M << 31 | S << 29 | 0b11110 << 24 | type << 22 | 1 << 21 |                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1145
        rm->encoding() << 16 | cond << 12 | 0b11 << 10 | rn->encoding() << 5 | rd->encoding()); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1146
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1147
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1148
  F(fcsel_s,   0, 0, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1149
  F(fcsel_d,   0, 0, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1150
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1151
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1152
#define F(mnemonic, M, S, type, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1153
  void mnemonic(FloatRegister rd, FloatRegister rn) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1154
    emit_int32(M << 31 | S << 29 | 0b11110 << 24 | type << 22 | 1 << 21 |      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1155
        opcode << 15 | 0b10000 << 10 | rn->encoding() << 5 | rd->encoding());  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1156
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1157
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1158
  F(fmov_s,   0, 0, 0b00, 0b000000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1159
  F(fabs_s,   0, 0, 0b00, 0b000001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1160
  F(fneg_s,   0, 0, 0b00, 0b000010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1161
  F(fsqrt_s,  0, 0, 0b00, 0b000011)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1162
  F(fcvt_ds,  0, 0, 0b00, 0b000101)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1163
  F(fcvt_hs,  0, 0, 0b00, 0b000111)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1164
  F(frintn_s, 0, 0, 0b00, 0b001000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1165
  F(frintp_s, 0, 0, 0b00, 0b001001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1166
  F(frintm_s, 0, 0, 0b00, 0b001010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1167
  F(frintz_s, 0, 0, 0b00, 0b001011)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1168
  F(frinta_s, 0, 0, 0b00, 0b001100)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1169
  F(frintx_s, 0, 0, 0b00, 0b001110)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1170
  F(frinti_s, 0, 0, 0b00, 0b001111)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1171
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1172
  F(fmov_d,   0, 0, 0b01, 0b000000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1173
  F(fabs_d,   0, 0, 0b01, 0b000001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1174
  F(fneg_d,   0, 0, 0b01, 0b000010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1175
  F(fsqrt_d,  0, 0, 0b01, 0b000011)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1176
  F(fcvt_sd,  0, 0, 0b01, 0b000100)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1177
  F(fcvt_hd,  0, 0, 0b01, 0b000111)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1178
  F(frintn_d, 0, 0, 0b01, 0b001000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1179
  F(frintp_d, 0, 0, 0b01, 0b001001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1180
  F(frintm_d, 0, 0, 0b01, 0b001010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1181
  F(frintz_d, 0, 0, 0b01, 0b001011)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1182
  F(frinta_d, 0, 0, 0b01, 0b001100)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1183
  F(frintx_d, 0, 0, 0b01, 0b001110)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1184
  F(frinti_d, 0, 0, 0b01, 0b001111)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1185
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1186
  F(fcvt_sh,  0, 0, 0b11, 0b000100)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1187
  F(fcvt_dh,  0, 0, 0b11, 0b000101)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1188
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1189
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1190
#define F(mnemonic, M, S, type, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1191
  void mnemonic(FloatRegister rd, FloatRegister rn, FloatRegister rm) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1192
    emit_int32(M << 31 | S << 29 | 0b11110 << 24 | type << 22 | 1 << 21 |                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1193
        rm->encoding() << 16 | opcode << 12 | 0b10 << 10 | rn->encoding() << 5 | rd->encoding());  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1194
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1195
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1196
  F(fmul_s,   0, 0, 0b00, 0b0000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1197
  F(fdiv_s,   0, 0, 0b00, 0b0001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1198
  F(fadd_s,   0, 0, 0b00, 0b0010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1199
  F(fsub_s,   0, 0, 0b00, 0b0011)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1200
  F(fmax_s,   0, 0, 0b00, 0b0100)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1201
  F(fmin_s,   0, 0, 0b00, 0b0101)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1202
  F(fmaxnm_s, 0, 0, 0b00, 0b0110)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1203
  F(fminnm_s, 0, 0, 0b00, 0b0111)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1204
  F(fnmul_s,  0, 0, 0b00, 0b1000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1205
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1206
  F(fmul_d,   0, 0, 0b01, 0b0000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1207
  F(fdiv_d,   0, 0, 0b01, 0b0001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1208
  F(fadd_d,   0, 0, 0b01, 0b0010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1209
  F(fsub_d,   0, 0, 0b01, 0b0011)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1210
  F(fmax_d,   0, 0, 0b01, 0b0100)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1211
  F(fmin_d,   0, 0, 0b01, 0b0101)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1212
  F(fmaxnm_d, 0, 0, 0b01, 0b0110)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1213
  F(fminnm_d, 0, 0, 0b01, 0b0111)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1214
  F(fnmul_d,  0, 0, 0b01, 0b1000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1215
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1216
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1217
#define F(mnemonic, M, S, type, o1, o0) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1218
  void mnemonic(FloatRegister rd, FloatRegister rn, FloatRegister rm, FloatRegister ra) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1219
    emit_int32(M << 31 | S << 29 | 0b11111 << 24 | type << 22 | o1 << 21 | rm->encoding() << 16 |  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1220
         o0 << 15 | ra->encoding() << 10 | rn->encoding() << 5 | rd->encoding());                  \
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1223
  F(fmadd_s,  0, 0, 0b00, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1224
  F(fmsub_s,  0, 0, 0b00, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1225
  F(fnmadd_s, 0, 0, 0b00, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1226
  F(fnmsub_s, 0, 0, 0b00, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1227
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1228
  F(fmadd_d,  0, 0, 0b01, 0, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1229
  F(fmsub_d,  0, 0, 0b01, 0, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1230
  F(fnmadd_d, 0, 0, 0b01, 1, 0)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1231
  F(fnmsub_d, 0, 0, 0b01, 1, 1)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1232
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1233
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1234
#define F(mnemonic, M, S, type) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1235
  void mnemonic(FloatRegister rd, int imm8) { \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1236
    assert ((imm8 >> 8) == 0, "immediate is out of range");                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1237
    emit_int32(M << 31 | S << 29 | 0b11110 << 24 | type << 22 | 1 << 21 |  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1238
         imm8 << 13 | 0b100 << 10 | rd->encoding());                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1239
  }
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
  F(fmov_s, 0, 0, 0b00)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1242
  F(fmov_d, 0, 0, 0b01)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1243
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1244
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1245
#define F(mnemonic, sf, S, type, rmode, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1246
  void mnemonic(Register rd, FloatRegister rn) {                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1247
    emit_int32(sf << 31 | S << 29 | 0b11110 << 24 | type << 22 | 1 << 21 |           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1248
         rmode << 19 | opcode << 16 | rn->encoding() << 5 | rd->encoding_with_zr()); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1249
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1250
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1251
  F(fcvtns_ws, 0, 0, 0b00, 0b00, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1252
  F(fcvtnu_ws, 0, 0, 0b00, 0b00, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1253
  F(fcvtas_ws, 0, 0, 0b00, 0b00, 0b100)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1254
  F(fcvtau_ws, 0, 0, 0b00, 0b00, 0b101)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1255
  F(fmov_ws,   0, 0, 0b00, 0b00, 0b110)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1256
  F(fcvtps_ws, 0, 0, 0b00, 0b01, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1257
  F(fcvtpu_ws, 0, 0, 0b00, 0b01, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1258
  F(fcvtms_ws, 0, 0, 0b00, 0b10, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1259
  F(fcvtmu_ws, 0, 0, 0b00, 0b10, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1260
  F(fcvtzs_ws, 0, 0, 0b00, 0b11, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1261
  F(fcvtzu_ws, 0, 0, 0b00, 0b11, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1262
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1263
  F(fcvtns_wd, 0, 0, 0b01, 0b00, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1264
  F(fcvtnu_wd, 0, 0, 0b01, 0b00, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1265
  F(fcvtas_wd, 0, 0, 0b01, 0b00, 0b100)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1266
  F(fcvtau_wd, 0, 0, 0b01, 0b00, 0b101)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1267
  F(fcvtps_wd, 0, 0, 0b01, 0b01, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1268
  F(fcvtpu_wd, 0, 0, 0b01, 0b01, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1269
  F(fcvtms_wd, 0, 0, 0b01, 0b10, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1270
  F(fcvtmu_wd, 0, 0, 0b01, 0b10, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1271
  F(fcvtzs_wd, 0, 0, 0b01, 0b11, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1272
  F(fcvtzu_wd, 0, 0, 0b01, 0b11, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1273
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1274
  F(fcvtns_xs, 1, 0, 0b00, 0b00, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1275
  F(fcvtnu_xs, 1, 0, 0b00, 0b00, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1276
  F(fcvtas_xs, 1, 0, 0b00, 0b00, 0b100)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1277
  F(fcvtau_xs, 1, 0, 0b00, 0b00, 0b101)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1278
  F(fcvtps_xs, 1, 0, 0b00, 0b01, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1279
  F(fcvtpu_xs, 1, 0, 0b00, 0b01, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1280
  F(fcvtms_xs, 1, 0, 0b00, 0b10, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1281
  F(fcvtmu_xs, 1, 0, 0b00, 0b10, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1282
  F(fcvtzs_xs, 1, 0, 0b00, 0b11, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1283
  F(fcvtzu_xs, 1, 0, 0b00, 0b11, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1284
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1285
  F(fcvtns_xd, 1, 0, 0b01, 0b00, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1286
  F(fcvtnu_xd, 1, 0, 0b01, 0b00, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1287
  F(fcvtas_xd, 1, 0, 0b01, 0b00, 0b100)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1288
  F(fcvtau_xd, 1, 0, 0b01, 0b00, 0b101)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1289
  F(fmov_xd,   1, 0, 0b01, 0b00, 0b110)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1290
  F(fcvtps_xd, 1, 0, 0b01, 0b01, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1291
  F(fcvtpu_xd, 1, 0, 0b01, 0b01, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1292
  F(fcvtms_xd, 1, 0, 0b01, 0b10, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1293
  F(fcvtmu_xd, 1, 0, 0b01, 0b10, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1294
  F(fcvtzs_xd, 1, 0, 0b01, 0b11, 0b000)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1295
  F(fcvtzu_xd, 1, 0, 0b01, 0b11, 0b001)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1296
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1297
  F(fmov_xq,   1, 0, 0b10, 0b01, 0b110)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1298
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1299
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1300
#define F(mnemonic, sf, S, type, rmode, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1301
  void mnemonic(FloatRegister rd, Register rn) {                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1302
    emit_int32(sf << 31 | S << 29 | 0b11110 << 24 | type << 22 | 1 << 21 |           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1303
         rmode << 19 | opcode << 16 | rn->encoding_with_zr() << 5 | rd->encoding()); \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1304
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1305
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1306
  F(scvtf_sw,  0, 0, 0b00, 0b00, 0b010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1307
  F(ucvtf_sw,  0, 0, 0b00, 0b00, 0b011)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1308
  F(fmov_sw,   0, 0, 0b00, 0b00, 0b111)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1309
  F(scvtf_dw,  0, 0, 0b01, 0b00, 0b010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1310
  F(ucvtf_dw,  0, 0, 0b01, 0b00, 0b011)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1311
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1312
  F(scvtf_sx,  1, 0, 0b00, 0b00, 0b010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1313
  F(ucvtf_sx,  1, 0, 0b00, 0b00, 0b011)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1314
  F(scvtf_dx,  1, 0, 0b01, 0b00, 0b010)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1315
  F(ucvtf_dx,  1, 0, 0b01, 0b00, 0b011)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1316
  F(fmov_dx,   1, 0, 0b01, 0b00, 0b111)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1317
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1318
  F(fmov_qx,   1, 0, 0b10, 0b01, 0b111)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1319
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1320
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1321
#define F(mnemonic, opcode) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1322
  void mnemonic(FloatRegister Vd, FloatRegister Vn) {                                     \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1323
    emit_int32( opcode << 10 | Vn->encoding() << 5 | Vd->encoding());             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1324
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1325
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1326
  F(aese, 0b0100111000101000010010);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1327
  F(aesd, 0b0100111000101000010110);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1328
  F(aesmc, 0b0100111000101000011010);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1329
  F(aesimc, 0b0100111000101000011110);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1330
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1331
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1332
#ifdef COMPILER2
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1333
  typedef VFP::double_num double_num;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1334
  typedef VFP::float_num  float_num;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1335
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1336
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1337
  void vcnt(FloatRegister Dd, FloatRegister Dn, int quad = 0, int size = 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1338
    // emitted at VM startup to detect whether the instruction is available
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1339
    assert(!VM_Version::is_initialized() || VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1340
    assert(size == 0, "illegal size value");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1341
    emit_int32(0x0e205800 | quad << 30 | size << 22 | Dn->encoding() << 5 | Dd->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1342
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1343
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1344
#ifdef COMPILER2
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1345
  void addv(FloatRegister Dd, FloatRegister Dm, int quad, int size) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1346
    // emitted at VM startup to detect whether the instruction is available
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1347
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1348
    assert((quad & ~1) == 0, "illegal value");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1349
    assert(size >= 0 && size < 3, "illegal value");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1350
    assert(((size << 1) | quad) != 4, "illegal values (size 2, quad 0)");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1351
    emit_int32(0x0e31b800 | quad << 30 | size << 22 | Dm->encoding() << 5 | Dd->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1352
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1353
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1354
  enum VElem_Size {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1355
    VELEM_SIZE_8  = 0x00,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1356
    VELEM_SIZE_16 = 0x01,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1357
    VELEM_SIZE_32 = 0x02,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1358
    VELEM_SIZE_64 = 0x03
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1359
  };
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1360
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1361
  enum VLD_Type {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1362
    VLD1_TYPE_1_REG  = 0b0111,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1363
    VLD1_TYPE_2_REGS = 0b1010,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1364
    VLD1_TYPE_3_REGS = 0b0110,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1365
    VLD1_TYPE_4_REGS = 0b0010
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1366
  };
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1367
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1368
  enum VFloat_Arith_Size {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1369
    VFA_SIZE_F32 = 0b0,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1370
    VFA_SIZE_F64 = 0b1
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1371
  };
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1372
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1373
#define F(mnemonic, U, S, P) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1374
  void mnemonic(FloatRegister fd, FloatRegister fn, FloatRegister fm,    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1375
                int size, int quad) {                                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1376
    assert(VM_Version::has_simd(), "simd instruction");                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1377
    assert(!(size == VFA_SIZE_F64 && !quad), "reserved");                \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1378
    assert((size & 1) == size, "overflow");                              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1379
    emit_int32(quad << 30 | U << 29 | 0b01110 << 24 |                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1380
               S << 23 | size << 22 | 1 << 21 | P << 11 | 1 << 10 |      \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1381
               fm->encoding() << 16 |                                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1382
               fn->encoding() <<  5 |                                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1383
               fd->encoding());                                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1384
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1385
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1386
  F(vaddF, 0, 0, 0b11010)  // Vd = Vn + Vm (float)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1387
  F(vsubF, 0, 1, 0b11010)  // Vd = Vn - Vm (float)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1388
  F(vmulF, 1, 0, 0b11011)  // Vd = Vn - Vm (float)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1389
  F(vdivF, 1, 0, 0b11111)  // Vd = Vn / Vm (float)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1390
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1391
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1392
#define F(mnemonic, U) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1393
  void mnemonic(FloatRegister fd, FloatRegister fm, FloatRegister fn,    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1394
                int size, int quad) {                                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1395
    assert(VM_Version::has_simd(), "simd instruction");                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1396
    assert(!(size == VELEM_SIZE_64 && !quad), "reserved");               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1397
    assert((size & 0b11) == size, "overflow");                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1398
    int R = 0; /* rounding */                                            \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1399
    int S = 0; /* saturating */                                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1400
    emit_int32(quad << 30 | U << 29 | 0b01110 << 24 | size << 22 |       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1401
               1 << 21 | R << 12 | S << 11 | 0b10001 << 10 |             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1402
               fm->encoding() << 16 |                                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1403
               fn->encoding() <<  5 |                                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1404
               fd->encoding());                                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1405
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1406
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1407
  F(vshlSI, 0)  // Vd = ashift(Vn,Vm) (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1408
  F(vshlUI, 1)  // Vd = lshift(Vn,Vm) (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1409
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1410
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1411
#define F(mnemonic, U, P, M) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1412
  void mnemonic(FloatRegister fd, FloatRegister fn, FloatRegister fm,    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1413
                int size, int quad) {                                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1414
    assert(VM_Version::has_simd(), "simd instruction");                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1415
    assert(!(size == VELEM_SIZE_64 && !quad), "reserved");               \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1416
    assert(!(size == VELEM_SIZE_64 && M), "reserved");                   \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1417
    assert((size & 0b11) == size, "overflow");                           \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1418
    emit_int32(quad << 30 | U << 29 | 0b01110 << 24 | size << 22 |       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1419
               1 << 21 | P << 11 | 1 << 10 |                             \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1420
               fm->encoding() << 16 |                                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1421
               fn->encoding() <<  5 |                                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1422
               fd->encoding());                                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1423
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1424
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1425
  F(vmulI, 0, 0b10011,  true)  // Vd = Vn * Vm (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1426
  F(vaddI, 0, 0b10000, false)  // Vd = Vn + Vm (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1427
  F(vsubI, 1, 0b10000, false)  // Vd = Vn - Vm (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1428
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1429
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1430
#define F(mnemonic, U, O) \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1431
  void mnemonic(FloatRegister fd, FloatRegister fn, FloatRegister fm,    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1432
                int quad) {                                              \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1433
    assert(VM_Version::has_simd(), "simd instruction");                  \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1434
    emit_int32(quad << 30 | U << 29 | 0b01110 << 24 | O << 22 |          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1435
               1 << 21 | 0b00011 << 11 | 1 << 10 |                       \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1436
               fm->encoding() << 16 |                                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1437
               fn->encoding() <<  5 |                                    \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1438
               fd->encoding());                                          \
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1439
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1440
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1441
  F(vandI, 0, 0b00)  // Vd = Vn & Vm (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1442
  F(vorI,  0, 0b10)  // Vd = Vn | Vm (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1443
  F(vxorI, 1, 0b00)  // Vd = Vn ^ Vm (int)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1444
#undef F
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1445
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1446
  void vnegI(FloatRegister fd, FloatRegister fn, int size, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1447
    int U = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1448
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1449
    assert(quad || size != VELEM_SIZE_64, "reserved");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1450
    emit_int32(quad << 30 | U << 29 | 0b01110 << 24 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1451
              size << 22 | 0b100000101110 << 10 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1452
              fn->encoding() << 5 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1453
              fd->encoding() << 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1454
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1455
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1456
  void vshli(FloatRegister fd, FloatRegister fn, int esize, int imm, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1457
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1458
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1459
    if (imm >= esize) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1460
      // maximum shift gives all zeroes, direction doesn't matter,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1461
      // but only available for shift right
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1462
      vshri(fd, fn, esize, esize, true /* unsigned */, quad);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1463
      return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1464
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1465
    assert(imm >= 0 && imm < esize, "out of range");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1466
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1467
    int imm7 = esize + imm;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1468
    int immh = imm7 >> 3;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1469
    assert(immh != 0, "encoding constraint");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1470
    assert((uint)immh < 16, "sanity");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1471
    assert(((immh >> 2) | quad) != 0b10, "reserved");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1472
    emit_int32(quad << 30 | 0b011110 << 23 | imm7 << 16 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1473
               0b010101 << 10 | fn->encoding() << 5 | fd->encoding() << 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1474
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1475
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1476
  void vshri(FloatRegister fd, FloatRegister fn, int esize, int imm,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1477
             bool U /* unsigned */, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1478
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1479
    assert(imm > 0, "out of range");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1480
    if (imm >= esize) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1481
      // maximum shift (all zeroes)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1482
      imm = esize;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1483
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1484
    int imm7 = 2 * esize - imm ;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1485
    int immh = imm7 >> 3;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1486
    assert(immh != 0, "encoding constraint");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1487
    assert((uint)immh < 16, "sanity");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1488
    assert(((immh >> 2) | quad) != 0b10, "reserved");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1489
    emit_int32(quad << 30 | U << 29 | 0b011110 << 23 | imm7 << 16 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1490
               0b000001 << 10 | fn->encoding() << 5 | fd->encoding() << 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1491
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1492
  void vshrUI(FloatRegister fd, FloatRegister fm, int size, int imm, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1493
    vshri(fd, fm, size, imm, true /* unsigned */, quad);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1494
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1495
  void vshrSI(FloatRegister fd, FloatRegister fm, int size, int imm, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1496
    vshri(fd, fm, size, imm, false /* signed */, quad);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1497
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1498
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1499
  void vld1(FloatRegister Vt, Address addr, VElem_Size size, int bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1500
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1501
    assert(bits == 128, "unsupported");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1502
    assert(addr.disp() == 0 || addr.disp() == 16, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1503
    int type = 0b11; // 2D
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1504
    int quad = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1505
    int L = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1506
    int opcode = VLD1_TYPE_1_REG;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1507
    emit_int32(quad << 30 | 0b11 << 26 | L << 22 | opcode << 12 | size << 10 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1508
               Vt->encoding() << 0 | addr.encoding_simd());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1509
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1510
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1511
  void vst1(FloatRegister Vt, Address addr, VElem_Size size, int bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1512
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1513
    assert(bits == 128, "unsupported");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1514
    assert(addr.disp() == 0 || addr.disp() == 16, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1515
    int type = 0b11; // 2D
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1516
    int quad = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1517
    int L = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1518
    int opcode = VLD1_TYPE_1_REG;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1519
    emit_int32(quad << 30 | 0b11 << 26 | L << 22 | opcode << 12 | size << 10 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1520
               Vt->encoding() << 0 | addr.encoding_simd());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1521
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1522
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1523
  void vld1(FloatRegister Vt, FloatRegister Vt2, Address addr, VElem_Size size, int bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1524
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1525
    assert(bits == 128, "unsupported");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1526
    assert(Vt->successor() == Vt2, "Registers must be ordered");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1527
    assert(addr.disp() == 0 || addr.disp() == 32, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1528
    int type = 0b11; // 2D
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1529
    int quad = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1530
    int L = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1531
    int opcode = VLD1_TYPE_2_REGS;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1532
    emit_int32(quad << 30 | 0b11 << 26 | L << 22 | opcode << 12 | size << 10 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1533
               Vt->encoding() << 0 | addr.encoding_simd());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1534
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1535
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1536
  void vst1(FloatRegister Vt, FloatRegister Vt2, Address addr, VElem_Size size, int bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1537
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1538
    assert(Vt->successor() == Vt2, "Registers must be ordered");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1539
    assert(bits == 128, "unsupported");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1540
    assert(addr.disp() == 0 || addr.disp() == 32, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1541
    int type = 0b11; // 2D
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1542
    int quad = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1543
    int L = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1544
    int opcode = VLD1_TYPE_2_REGS;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1545
    emit_int32(quad << 30 | 0b11 << 26 | L << 22 | opcode << 12 | size << 10 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1546
               Vt->encoding() << 0 | addr.encoding_simd());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1547
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1548
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1549
  void vld1(FloatRegister Vt, FloatRegister Vt2, FloatRegister Vt3,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1550
            Address addr, VElem_Size size, int bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1551
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1552
    assert(bits == 128, "unsupported");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1553
    assert(Vt->successor() == Vt2 && Vt2->successor() == Vt3,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1554
          "Registers must be ordered");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1555
    assert(addr.disp() == 0 || addr.disp() == 48, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1556
    int type = 0b11; // 2D
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1557
    int quad = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1558
    int L = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1559
    int opcode = VLD1_TYPE_3_REGS;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1560
    emit_int32(quad << 30 | 0b11 << 26 | L << 22 | opcode << 12 | size << 10 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1561
               Vt->encoding() << 0 | addr.encoding_simd());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1562
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1563
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1564
  void vst1(FloatRegister Vt, FloatRegister Vt2, FloatRegister Vt3,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1565
            Address addr, VElem_Size size, int bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1566
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1567
    assert(bits == 128, "unsupported");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1568
    assert(Vt->successor() == Vt2 &&  Vt2->successor() == Vt3,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1569
           "Registers must be ordered");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1570
    assert(addr.disp() == 0 || addr.disp() == 48, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1571
    int type = 0b11; // 2D
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1572
    int quad = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1573
    int L = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1574
    int opcode = VLD1_TYPE_3_REGS;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1575
    emit_int32(quad << 30 | 0b11 << 26 | L << 22 | opcode << 12 | size << 10 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1576
               Vt->encoding() << 0 | addr.encoding_simd());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1577
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1578
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1579
  void vld1(FloatRegister Vt, FloatRegister Vt2, FloatRegister Vt3,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1580
            FloatRegister Vt4, Address addr, VElem_Size size, int bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1581
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1582
    assert(bits == 128, "unsupported");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1583
    assert(Vt->successor() == Vt2 && Vt2->successor() == Vt3 &&
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1584
           Vt3->successor() == Vt4, "Registers must be ordered");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1585
    assert(addr.disp() == 0 || addr.disp() == 64, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1586
    int type = 0b11; // 2D
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1587
    int quad = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1588
    int L = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1589
    int opcode = VLD1_TYPE_4_REGS;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1590
    emit_int32(quad << 30 | 0b11 << 26 | L << 22 | opcode << 12 | size << 10 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1591
               Vt->encoding() << 0 | addr.encoding_simd());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1592
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1593
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1594
  void vst1(FloatRegister Vt, FloatRegister Vt2, FloatRegister Vt3,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1595
            FloatRegister Vt4,  Address addr, VElem_Size size, int bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1596
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1597
    assert(bits == 128, "unsupported");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1598
    assert(Vt->successor() == Vt2 && Vt2->successor() == Vt3 &&
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1599
           Vt3->successor() == Vt4, "Registers must be ordered");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1600
    assert(addr.disp() == 0 || addr.disp() == 64, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1601
    int type = 0b11; // 2D
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1602
    int quad = 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1603
    int L = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1604
    int opcode = VLD1_TYPE_4_REGS;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1605
    emit_int32(quad << 30 | 0b11 << 26 | L << 22 | opcode << 12 | size << 10 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1606
               Vt->encoding() << 0 | addr.encoding_simd());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1607
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1608
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1609
  void rev32(FloatRegister Vd, FloatRegister Vn, VElem_Size size, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1610
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1611
    assert(size == VELEM_SIZE_8 || size == VELEM_SIZE_16, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1612
    emit_int32(quad << 30 | 0b101110 << 24 | size << 22 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1613
               0b100000000010 << 10 | Vn->encoding() << 5 | Vd->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1614
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1615
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1616
  void eor(FloatRegister Vd, FloatRegister Vn,  FloatRegister Vm, VElem_Size size, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1617
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1618
    assert(size == VELEM_SIZE_8, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1619
    emit_int32(quad << 30 | 0b101110001 << 21 | Vm->encoding() << 16 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1620
               0b000111 << 10 | Vn->encoding() << 5 | Vd->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1621
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1622
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1623
  void orr(FloatRegister Vd, FloatRegister Vn,  FloatRegister Vm, VElem_Size size, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1624
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1625
    assert(size == VELEM_SIZE_8, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1626
    emit_int32(quad << 30 | 0b001110101 << 21 | Vm->encoding() << 16 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1627
               0b000111 << 10 | Vn->encoding() << 5 | Vd->encoding());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1628
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1629
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1630
  void vmovI(FloatRegister Dd, int imm8, VElem_Size size, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1631
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1632
    assert(imm8 >= 0 && imm8 < 256, "out of range");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1633
    int op;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1634
    int cmode;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1635
    switch (size) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1636
    case VELEM_SIZE_8:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1637
      op = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1638
      cmode = 0b1110;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1639
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1640
    case VELEM_SIZE_16:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1641
      op = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1642
      cmode = 0b1000;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1643
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1644
    case VELEM_SIZE_32:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1645
      op = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1646
      cmode = 0b0000;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1647
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1648
    default:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1649
      cmode = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1650
      ShouldNotReachHere();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1651
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1652
    int abc = imm8 >> 5;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1653
    int defgh = imm8 & 0b11111;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1654
    emit_int32(quad << 30 | op << 29 | 0b1111 << 24 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1655
               abc << 16 | cmode << 12 | 0b01 << 10 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1656
               defgh << 5 | Dd->encoding() << 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1657
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1658
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1659
  void vdupI(FloatRegister Dd, Register Rn, VElem_Size size, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1660
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1661
    assert(size <= 3, "unallocated encoding");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1662
    assert(size != 3 || quad == 1, "reserved");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1663
    int imm5 = 1 << size;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1664
#ifdef ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1665
    switch (size) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1666
    case VELEM_SIZE_8:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1667
      assert(imm5 == 0b00001, "sanity");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1668
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1669
    case VELEM_SIZE_16:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1670
      assert(imm5 == 0b00010, "sanity");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1671
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1672
    case VELEM_SIZE_32:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1673
      assert(imm5 == 0b00100, "sanity");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1674
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1675
    case VELEM_SIZE_64:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1676
      assert(imm5 == 0b01000, "sanity");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1677
      break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1678
    default:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1679
      ShouldNotReachHere();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1680
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1681
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1682
    emit_int32(quad << 30 | 0b111 << 25 | 0b11 << 10 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1683
               imm5 << 16 | Rn->encoding() << 5 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1684
               Dd->encoding() << 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1685
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1686
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1687
  void vdup(FloatRegister Vd, FloatRegister Vn, VElem_Size size, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1688
    assert(VM_Version::has_simd(), "simd instruction");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1689
    int index = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1690
    int bytes = 1 << size;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1691
    int range = 16 / bytes;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1692
    assert(index < range, "overflow");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1693
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1694
    assert(size != VELEM_SIZE_64 || quad, "reserved");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1695
    assert(8 << VELEM_SIZE_8  ==  8, "sanity");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1696
    assert(8 << VELEM_SIZE_16 == 16, "sanity");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1697
    assert(8 << VELEM_SIZE_32 == 32, "sanity");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1698
    assert(8 << VELEM_SIZE_64 == 64, "sanity");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1699
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1700
    int imm5 = (index << (size + 1)) | bytes;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1701
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1702
    emit_int32(quad << 30 | 0b001110000 << 21 | imm5 << 16 | 0b000001 << 10 |
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1703
               Vn->encoding() << 5 | Vd->encoding() << 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1704
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1705
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1706
  void vdupF(FloatRegister Vd, FloatRegister Vn, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1707
    vdup(Vd, Vn, VELEM_SIZE_32, quad);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1708
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1709
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1710
  void vdupD(FloatRegister Vd, FloatRegister Vn, int quad) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1711
    vdup(Vd, Vn, VELEM_SIZE_64, quad);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1712
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1713
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1714
};
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1715
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1716
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1717
#endif // CPU_ARM_VM_ASSEMBLER_ARM_64_HPP