src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64BaseAssembler.java
author dlong
Thu, 14 Nov 2019 12:21:00 -0800
changeset 59095 03fbcd06b4c0
parent 58299 6df94ce3ab2f
permissions -rw-r--r--
8233841: Update Graal Reviewed-by: kvn
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     1
/*
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
     2
 * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     4
 *
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     7
 * published by the Free Software Foundation.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     8
 *
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    13
 * accompanied this code).
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    14
 *
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    18
 *
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    21
 * questions.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    22
 */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    23
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    24
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    25
package org.graalvm.compiler.asm.amd64;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    26
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    27
import static jdk.vm.ci.amd64.AMD64.MASK;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    28
import static jdk.vm.ci.amd64.AMD64.XMM;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    29
import static jdk.vm.ci.amd64.AMD64.r12;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    30
import static jdk.vm.ci.amd64.AMD64.r13;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    31
import static jdk.vm.ci.amd64.AMD64.rbp;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    32
import static jdk.vm.ci.amd64.AMD64.rsp;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    33
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.B0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    34
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.B1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    35
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.Z0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    36
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.Z1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    37
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.L128;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    38
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.L256;
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
    39
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.L512;
51736
42d99cb7f50f 8210478: Update Graal
iveresov
parents: 51436
diff changeset
    40
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.LZ;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    41
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.M_0F;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    42
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.M_0F38;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    43
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.M_0F3A;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    44
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.P_;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    45
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.P_66;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    46
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.P_F2;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    47
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.P_F3;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    48
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.W0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    49
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.W1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    50
import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.WIG;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    51
import static org.graalvm.compiler.core.common.NumUtil.isByte;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    52
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    53
import org.graalvm.compiler.asm.Assembler;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    54
import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    55
import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    56
import org.graalvm.compiler.debug.GraalError;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    57
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    58
import jdk.vm.ci.amd64.AMD64;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    59
import jdk.vm.ci.amd64.AMD64.CPUFeature;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    60
import jdk.vm.ci.amd64.AMD64Kind;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    61
import jdk.vm.ci.code.Register;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
    62
import jdk.vm.ci.code.Register.RegisterCategory;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    63
import jdk.vm.ci.code.TargetDescription;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    64
import jdk.vm.ci.meta.PlatformKind;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    65
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    66
/**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    67
 * This class implements an assembler that can encode most X86 instructions.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    68
 */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    69
public abstract class AMD64BaseAssembler extends Assembler {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    70
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    71
    private final SIMDEncoder simdEncoder;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    72
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    73
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    74
     * Constructs an assembler for the AMD64 architecture.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    75
     */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    76
    public AMD64BaseAssembler(TargetDescription target) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    77
        super(target);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    78
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    79
        if (supports(CPUFeature.AVX)) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    80
            simdEncoder = new VEXEncoderImpl();
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    81
        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    82
            simdEncoder = new SSEEncoderImpl();
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    83
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    84
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    85
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    86
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    87
     * The x86 operand sizes.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    88
     */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    89
    public enum OperandSize {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    90
        BYTE(1, AMD64Kind.BYTE) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    91
            @Override
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    92
            protected void emitImmediate(AMD64BaseAssembler asm, int imm) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    93
                assert imm == (byte) imm;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    94
                asm.emitByte(imm);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    95
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    96
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    97
            @Override
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    98
            protected int immediateSize() {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    99
                return 1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   100
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   101
        },
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   102
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   103
        WORD(2, AMD64Kind.WORD, 0x66) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   104
            @Override
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   105
            protected void emitImmediate(AMD64BaseAssembler asm, int imm) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   106
                assert imm == (short) imm;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   107
                asm.emitShort(imm);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   108
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   109
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   110
            @Override
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   111
            protected int immediateSize() {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   112
                return 2;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   113
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   114
        },
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   115
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   116
        DWORD(4, AMD64Kind.DWORD) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   117
            @Override
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   118
            protected void emitImmediate(AMD64BaseAssembler asm, int imm) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   119
                asm.emitInt(imm);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   120
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   121
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   122
            @Override
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   123
            protected int immediateSize() {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   124
                return 4;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   125
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   126
        },
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   127
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   128
        QWORD(8, AMD64Kind.QWORD) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   129
            @Override
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   130
            protected void emitImmediate(AMD64BaseAssembler asm, int imm) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   131
                asm.emitInt(imm);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   132
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   133
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   134
            @Override
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   135
            protected int immediateSize() {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   136
                return 4;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   137
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   138
        },
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   139
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   140
        SS(4, AMD64Kind.SINGLE, 0xF3, true),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   141
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   142
        SD(8, AMD64Kind.DOUBLE, 0xF2, true),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   143
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   144
        PS(16, AMD64Kind.V128_SINGLE, true),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   145
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   146
        PD(16, AMD64Kind.V128_DOUBLE, 0x66, true);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   147
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   148
        private final int sizePrefix;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   149
        private final int bytes;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   150
        private final boolean xmm;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   151
        private final AMD64Kind kind;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   152
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   153
        OperandSize(int bytes, AMD64Kind kind) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   154
            this(bytes, kind, 0);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   155
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   156
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   157
        OperandSize(int bytes, AMD64Kind kind, int sizePrefix) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   158
            this(bytes, kind, sizePrefix, false);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   159
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   160
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   161
        OperandSize(int bytes, AMD64Kind kind, boolean xmm) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   162
            this(bytes, kind, 0, xmm);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   163
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   164
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   165
        OperandSize(int bytes, AMD64Kind kind, int sizePrefix, boolean xmm) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   166
            this.sizePrefix = sizePrefix;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   167
            this.bytes = bytes;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   168
            this.kind = kind;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   169
            this.xmm = xmm;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   170
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   171
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   172
        public int getSizePrefix() {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   173
            return sizePrefix;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   174
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   175
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   176
        public int getBytes() {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   177
            return bytes;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   178
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   179
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   180
        public boolean isXmmType() {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   181
            return xmm;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   182
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   183
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   184
        public AMD64Kind getKind() {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   185
            return kind;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   186
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   187
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   188
        public static OperandSize get(PlatformKind kind) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   189
            for (OperandSize operandSize : OperandSize.values()) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   190
                if (operandSize.kind.equals(kind)) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   191
                    return operandSize;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   192
                }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   193
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   194
            throw GraalError.shouldNotReachHere("Unexpected kind: " + kind.toString());
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   195
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   196
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   197
        /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   198
         * Emit an immediate of this size. Note that immediate {@link #QWORD} operands are encoded
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   199
         * as sign-extended 32-bit values.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   200
         *
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   201
         * @param asm
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   202
         * @param imm
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   203
         */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   204
        protected void emitImmediate(AMD64BaseAssembler asm, int imm) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   205
            throw new UnsupportedOperationException();
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   206
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   207
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   208
        protected int immediateSize() {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   209
            throw new UnsupportedOperationException();
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   210
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   211
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   212
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   213
    public static class OperandDataAnnotation extends CodeAnnotation {
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   214
        /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   215
         * The position (bytes from the beginning of the method) of the operand.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   216
         */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   217
        public final int operandPosition;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   218
        /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   219
         * The size of the operand, in bytes.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   220
         */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   221
        public final int operandSize;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   222
        /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   223
         * The position (bytes from the beginning of the method) of the next instruction. On AMD64,
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   224
         * RIP-relative operands are relative to this position.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   225
         */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   226
        public final int nextInstructionPosition;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   227
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   228
        OperandDataAnnotation(int instructionPosition, int operandPosition, int operandSize, int nextInstructionPosition) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   229
            super(instructionPosition);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   230
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   231
            this.operandPosition = operandPosition;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   232
            this.operandSize = operandSize;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   233
            this.nextInstructionPosition = nextInstructionPosition;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   234
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   235
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   236
        @Override
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   237
        public String toString() {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   238
            return getClass().getSimpleName() + " instruction [" + instructionPosition + ", " + nextInstructionPosition + "[ operand at " + operandPosition + " size " + operandSize;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   239
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   240
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   241
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   242
    protected void annotatePatchingImmediate(int operandOffset, int operandSize) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   243
        if (codePatchingAnnotationConsumer != null) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   244
            int pos = position();
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   245
            codePatchingAnnotationConsumer.accept(new OperandDataAnnotation(pos, pos + operandOffset, operandSize, pos + operandOffset + operandSize));
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   246
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   247
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   248
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   249
    public final boolean supports(CPUFeature feature) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   250
        return ((AMD64) target.arch).getFeatures().contains(feature);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   251
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   252
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   253
    protected static boolean inRC(RegisterCategory rc, Register r) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   254
        return r.getRegisterCategory().equals(rc);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   255
    }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   256
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   257
    protected static int encode(Register r) {
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   258
        assert r.encoding >= 0 && (inRC(XMM, r) ? r.encoding < 32 : r.encoding < 16) : "encoding out of range: " + r.encoding;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   259
        return r.encoding & 0x7;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   260
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   261
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   262
    private static final int MinEncodingNeedsRex = 8;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   263
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   264
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   265
     * Constants for X86 prefix bytes.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   266
     */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   267
    private static class Prefix {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   268
        private static final int REX = 0x40;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   269
        private static final int REXB = 0x41;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   270
        private static final int REXX = 0x42;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   271
        private static final int REXXB = 0x43;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   272
        private static final int REXR = 0x44;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   273
        private static final int REXRB = 0x45;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   274
        private static final int REXRX = 0x46;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   275
        private static final int REXRXB = 0x47;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   276
        private static final int REXW = 0x48;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   277
        private static final int REXWB = 0x49;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   278
        private static final int REXWX = 0x4A;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   279
        private static final int REXWXB = 0x4B;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   280
        private static final int REXWR = 0x4C;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   281
        private static final int REXWRB = 0x4D;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   282
        private static final int REXWRX = 0x4E;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   283
        private static final int REXWRXB = 0x4F;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   284
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   285
        private static final int VEX2 = 0xC5;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   286
        private static final int VEX3 = 0xC4;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   287
        private static final int EVEX = 0x62;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   288
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   289
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   290
    protected final void rexw() {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   291
        emitByte(Prefix.REXW);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   292
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   293
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   294
    protected final void prefix(Register reg) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   295
        prefix(reg, false);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   296
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   297
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   298
    protected final void prefix(Register reg, boolean byteinst) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   299
        int regEnc = reg.encoding;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   300
        if (regEnc >= 8) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   301
            emitByte(Prefix.REXB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   302
        } else if (byteinst && regEnc >= 4) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   303
            emitByte(Prefix.REX);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   304
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   305
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   306
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   307
    protected final void prefixq(Register reg) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   308
        if (reg.encoding < 8) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   309
            emitByte(Prefix.REXW);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   310
        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   311
            emitByte(Prefix.REXWB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   312
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   313
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   314
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   315
    protected final void prefix(Register dst, Register src) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   316
        prefix(dst, false, src, false);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   317
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   318
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   319
    protected final void prefix(Register dst, boolean dstIsByte, Register src, boolean srcIsByte) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   320
        int dstEnc = dst.encoding;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   321
        int srcEnc = src.encoding;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   322
        if (dstEnc < 8) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   323
            if (srcEnc >= 8) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   324
                emitByte(Prefix.REXB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   325
            } else if ((srcIsByte && srcEnc >= 4) || (dstIsByte && dstEnc >= 4)) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   326
                emitByte(Prefix.REX);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   327
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   328
        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   329
            if (srcEnc < 8) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   330
                emitByte(Prefix.REXR);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   331
            } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   332
                emitByte(Prefix.REXRB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   333
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   334
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   335
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   336
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   337
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   338
     * Creates prefix for the operands. If the given operands exceed 3 bits, the 4th bit is encoded
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   339
     * in the prefix.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   340
     */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   341
    protected final void prefixq(Register reg, Register rm) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   342
        int regEnc = reg.encoding;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   343
        int rmEnc = rm.encoding;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   344
        if (regEnc < 8) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   345
            if (rmEnc < 8) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   346
                emitByte(Prefix.REXW);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   347
            } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   348
                emitByte(Prefix.REXWB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   349
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   350
        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   351
            if (rmEnc < 8) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   352
                emitByte(Prefix.REXWR);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   353
            } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   354
                emitByte(Prefix.REXWRB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   355
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   356
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   357
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   358
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   359
    private static boolean needsRex(Register reg) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   360
        return reg.encoding >= MinEncodingNeedsRex;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   361
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   362
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   363
    protected final void prefix(AMD64Address adr) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   364
        if (needsRex(adr.getBase())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   365
            if (needsRex(adr.getIndex())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   366
                emitByte(Prefix.REXXB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   367
            } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   368
                emitByte(Prefix.REXB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   369
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   370
        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   371
            if (needsRex(adr.getIndex())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   372
                emitByte(Prefix.REXX);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   373
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   374
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   375
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   376
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   377
    protected final void prefixq(AMD64Address adr) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   378
        if (needsRex(adr.getBase())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   379
            if (needsRex(adr.getIndex())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   380
                emitByte(Prefix.REXWXB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   381
            } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   382
                emitByte(Prefix.REXWB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   383
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   384
        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   385
            if (needsRex(adr.getIndex())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   386
                emitByte(Prefix.REXWX);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   387
            } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   388
                emitByte(Prefix.REXW);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   389
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   390
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   391
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   392
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   393
    protected void prefixb(AMD64Address adr, Register reg) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   394
        prefix(adr, reg, true);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   395
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   396
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   397
    protected void prefix(AMD64Address adr, Register reg) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   398
        prefix(adr, reg, false);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   399
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   400
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   401
    protected void prefix(AMD64Address adr, Register reg, boolean byteinst) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   402
        if (reg.encoding < 8) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   403
            if (needsRex(adr.getBase())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   404
                if (needsRex(adr.getIndex())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   405
                    emitByte(Prefix.REXXB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   406
                } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   407
                    emitByte(Prefix.REXB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   408
                }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   409
            } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   410
                if (needsRex(adr.getIndex())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   411
                    emitByte(Prefix.REXX);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   412
                } else if (byteinst && reg.encoding >= 4) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   413
                    emitByte(Prefix.REX);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   414
                }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   415
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   416
        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   417
            if (needsRex(adr.getBase())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   418
                if (needsRex(adr.getIndex())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   419
                    emitByte(Prefix.REXRXB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   420
                } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   421
                    emitByte(Prefix.REXRB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   422
                }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   423
            } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   424
                if (needsRex(adr.getIndex())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   425
                    emitByte(Prefix.REXRX);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   426
                } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   427
                    emitByte(Prefix.REXR);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   428
                }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   429
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   430
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   431
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   432
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   433
    protected void prefixq(AMD64Address adr, Register src) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   434
        if (src.encoding < 8) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   435
            if (needsRex(adr.getBase())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   436
                if (needsRex(adr.getIndex())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   437
                    emitByte(Prefix.REXWXB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   438
                } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   439
                    emitByte(Prefix.REXWB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   440
                }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   441
            } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   442
                if (needsRex(adr.getIndex())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   443
                    emitByte(Prefix.REXWX);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   444
                } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   445
                    emitByte(Prefix.REXW);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   446
                }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   447
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   448
        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   449
            if (needsRex(adr.getBase())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   450
                if (needsRex(adr.getIndex())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   451
                    emitByte(Prefix.REXWRXB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   452
                } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   453
                    emitByte(Prefix.REXWRB);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   454
                }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   455
            } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   456
                if (needsRex(adr.getIndex())) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   457
                    emitByte(Prefix.REXWRX);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   458
                } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   459
                    emitByte(Prefix.REXWR);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   460
                }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   461
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   462
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   463
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   464
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   465
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   466
     * Get RXB bits for register-register instruction. In that encoding, ModRM.rm contains a
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   467
     * register index. The R bit extends the ModRM.reg field and the B bit extends the ModRM.rm
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   468
     * field. The X bit must be 0.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   469
     */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   470
    protected static int getRXB(Register reg, Register rm) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   471
        int rxb = (reg == null ? 0 : reg.encoding & 0x08) >> 1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   472
        rxb |= (rm == null ? 0 : rm.encoding & 0x08) >> 3;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   473
        return rxb;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   474
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   475
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   476
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   477
     * Get RXB bits for register-memory instruction. The R bit extends the ModRM.reg field. There
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   478
     * are two cases for the memory operand:<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   479
     * ModRM.rm contains the base register: In that case, B extends the ModRM.rm field and X = 0.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   480
     * <br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   481
     * There is an SIB byte: In that case, X extends SIB.index and B extends SIB.base.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   482
     */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   483
    protected static int getRXB(Register reg, AMD64Address rm) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   484
        int rxb = (reg == null ? 0 : reg.encoding & 0x08) >> 1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   485
        if (!rm.getIndex().equals(Register.None)) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   486
            rxb |= (rm.getIndex().encoding & 0x08) >> 2;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   487
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   488
        if (!rm.getBase().equals(Register.None)) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   489
            rxb |= (rm.getBase().encoding & 0x08) >> 3;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   490
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   491
        return rxb;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   492
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   493
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   494
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   495
     * Emit the ModR/M byte for one register operand and an opcode extension in the R field.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   496
     * <p>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   497
     * Format: [ 11 reg r/m ]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   498
     */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   499
    protected final void emitModRM(int reg, Register rm) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   500
        assert (reg & 0x07) == reg;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   501
        emitByte(0xC0 | (reg << 3) | (rm.encoding & 0x07));
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   502
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   503
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   504
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   505
     * Emit the ModR/M byte for two register operands.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   506
     * <p>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   507
     * Format: [ 11 reg r/m ]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   508
     */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   509
    protected final void emitModRM(Register reg, Register rm) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   510
        emitModRM(reg.encoding & 0x07, rm);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   511
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   512
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   513
    public static final int DEFAULT_DISP8_SCALE = 1;
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   514
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   515
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   516
     * Emits the ModR/M byte and optionally the SIB byte for one register and one memory operand.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   517
     *
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   518
     * @param force4Byte use 4 byte encoding for displacements that would normally fit in a byte
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   519
     */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   520
    protected final void emitOperandHelper(Register reg, AMD64Address addr, boolean force4Byte, int additionalInstructionSize) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   521
        assert !reg.equals(Register.None);
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   522
        emitOperandHelper(encode(reg), addr, force4Byte, additionalInstructionSize, DEFAULT_DISP8_SCALE);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   523
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   524
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   525
    protected final void emitOperandHelper(int reg, AMD64Address addr, int additionalInstructionSize) {
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   526
        emitOperandHelper(reg, addr, false, additionalInstructionSize, DEFAULT_DISP8_SCALE);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   527
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   528
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   529
    protected final void emitOperandHelper(Register reg, AMD64Address addr, int additionalInstructionSize) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   530
        assert !reg.equals(Register.None);
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   531
        emitOperandHelper(encode(reg), addr, false, additionalInstructionSize, DEFAULT_DISP8_SCALE);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   532
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   533
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   534
    protected final void emitOperandHelper(Register reg, AMD64Address addr, int additionalInstructionSize, int evexDisp8Scale) {
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   535
        assert !reg.equals(Register.None);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   536
        emitOperandHelper(encode(reg), addr, false, additionalInstructionSize, evexDisp8Scale);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   537
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   538
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   539
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   540
     * Emits the ModR/M byte and optionally the SIB byte for one memory operand and an opcode
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   541
     * extension in the R field.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   542
     *
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   543
     * @param force4Byte use 4 byte encoding for displacements that would normally fit in a byte
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   544
     * @param additionalInstructionSize the number of bytes that will be emitted after the operand,
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   545
     *            so that the start position of the next instruction can be computed even though
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   546
     *            this instruction has not been completely emitted yet.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   547
     * @param evexDisp8Scale the scaling factor for computing the compressed displacement of
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   548
     *            EVEX-encoded instructions. This scaling factor only matters when the emitted
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   549
     *            instruction uses one-byte-displacement form.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   550
     */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   551
    private void emitOperandHelper(int reg, AMD64Address addr, boolean force4Byte, int additionalInstructionSize, int evexDisp8Scale) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   552
        assert (reg & 0x07) == reg;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   553
        int regenc = reg << 3;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   554
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   555
        Register base = addr.getBase();
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   556
        Register index = addr.getIndex();
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   557
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   558
        Scale scale = addr.getScale();
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   559
        int disp = addr.getDisplacement();
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   560
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   561
        if (base.equals(AMD64.rip)) { // also matches addresses returned by getPlaceholder()
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   562
            // [00 000 101] disp32
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   563
            assert index.equals(Register.None) : "cannot use RIP relative addressing with index register";
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   564
            emitByte(0x05 | regenc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   565
            if (codePatchingAnnotationConsumer != null && addr.instructionStartPosition >= 0) {
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   566
                codePatchingAnnotationConsumer.accept(new OperandDataAnnotation(addr.instructionStartPosition, position(), 4, position() + 4 + additionalInstructionSize));
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   567
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   568
            emitInt(disp);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   569
        } else if (base.isValid()) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   570
            boolean overriddenForce4Byte = force4Byte;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   571
            int baseenc = base.isValid() ? encode(base) : 0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   572
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   573
            if (index.isValid()) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   574
                int indexenc = encode(index) << 3;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   575
                // [base + indexscale + disp]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   576
                if (disp == 0 && !base.equals(rbp) && !base.equals(r13)) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   577
                    // [base + indexscale]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   578
                    // [00 reg 100][ss index base]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   579
                    assert !index.equals(rsp) : "illegal addressing mode";
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   580
                    emitByte(0x04 | regenc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   581
                    emitByte(scale.log2 << 6 | indexenc | baseenc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   582
                } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   583
                    if (evexDisp8Scale > 1 && !overriddenForce4Byte) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   584
                        if (disp % evexDisp8Scale == 0) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   585
                            int newDisp = disp / evexDisp8Scale;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   586
                            if (isByte(newDisp)) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   587
                                disp = newDisp;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   588
                                assert isByte(disp) && !overriddenForce4Byte;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   589
                            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   590
                        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   591
                            overriddenForce4Byte = true;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   592
                        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   593
                    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   594
                    if (isByte(disp) && !overriddenForce4Byte) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   595
                        // [base + indexscale + imm8]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   596
                        // [01 reg 100][ss index base] imm8
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   597
                        assert !index.equals(rsp) : "illegal addressing mode";
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   598
                        emitByte(0x44 | regenc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   599
                        emitByte(scale.log2 << 6 | indexenc | baseenc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   600
                        emitByte(disp & 0xFF);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   601
                    } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   602
                        // [base + indexscale + disp32]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   603
                        // [10 reg 100][ss index base] disp32
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   604
                        assert !index.equals(rsp) : "illegal addressing mode";
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   605
                        emitByte(0x84 | regenc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   606
                        emitByte(scale.log2 << 6 | indexenc | baseenc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   607
                        emitInt(disp);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   608
                    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   609
                }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   610
            } else if (base.equals(rsp) || base.equals(r12)) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   611
                // [rsp + disp]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   612
                if (disp == 0) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   613
                    // [rsp]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   614
                    // [00 reg 100][00 100 100]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   615
                    emitByte(0x04 | regenc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   616
                    emitByte(0x24);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   617
                } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   618
                    if (evexDisp8Scale > 1 && !overriddenForce4Byte) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   619
                        if (disp % evexDisp8Scale == 0) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   620
                            int newDisp = disp / evexDisp8Scale;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   621
                            if (isByte(newDisp)) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   622
                                disp = newDisp;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   623
                                assert isByte(disp) && !overriddenForce4Byte;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   624
                            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   625
                        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   626
                            overriddenForce4Byte = true;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   627
                        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   628
                    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   629
                    if (isByte(disp) && !overriddenForce4Byte) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   630
                        // [rsp + imm8]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   631
                        // [01 reg 100][00 100 100] disp8
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   632
                        emitByte(0x44 | regenc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   633
                        emitByte(0x24);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   634
                        emitByte(disp & 0xFF);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   635
                    } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   636
                        // [rsp + imm32]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   637
                        // [10 reg 100][00 100 100] disp32
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   638
                        emitByte(0x84 | regenc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   639
                        emitByte(0x24);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   640
                        emitInt(disp);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   641
                    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   642
                }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   643
            } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   644
                // [base + disp]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   645
                assert !base.equals(rsp) && !base.equals(r12) : "illegal addressing mode";
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   646
                if (disp == 0 && !base.equals(rbp) && !base.equals(r13)) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   647
                    // [base]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   648
                    // [00 reg base]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   649
                    emitByte(0x00 | regenc | baseenc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   650
                } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   651
                    if (evexDisp8Scale > 1 && !overriddenForce4Byte) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   652
                        if (disp % evexDisp8Scale == 0) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   653
                            int newDisp = disp / evexDisp8Scale;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   654
                            if (isByte(newDisp)) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   655
                                disp = newDisp;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   656
                                assert isByte(disp) && !overriddenForce4Byte;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   657
                            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   658
                        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   659
                            overriddenForce4Byte = true;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   660
                        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   661
                    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   662
                    if (isByte(disp) && !overriddenForce4Byte) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   663
                        // [base + disp8]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   664
                        // [01 reg base] disp8
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   665
                        emitByte(0x40 | regenc | baseenc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   666
                        emitByte(disp & 0xFF);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   667
                    } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   668
                        // [base + disp32]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   669
                        // [10 reg base] disp32
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   670
                        emitByte(0x80 | regenc | baseenc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   671
                        emitInt(disp);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   672
                    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   673
                }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   674
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   675
        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   676
            if (index.isValid()) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   677
                int indexenc = encode(index) << 3;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   678
                // [indexscale + disp]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   679
                // [00 reg 100][ss index 101] disp32
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   680
                assert !index.equals(rsp) : "illegal addressing mode";
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   681
                emitByte(0x04 | regenc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   682
                emitByte(scale.log2 << 6 | indexenc | 0x05);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   683
                emitInt(disp);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   684
            } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   685
                // [disp] ABSOLUTE
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   686
                // [00 reg 100][00 100 101] disp32
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   687
                emitByte(0x04 | regenc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   688
                emitByte(0x25);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   689
                emitInt(disp);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   690
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   691
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   692
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   693
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   694
    private interface SIMDEncoder {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   695
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   696
        void simdPrefix(Register xreg, Register nds, AMD64Address adr, int sizePrefix, int opcodeEscapePrefix, boolean isRexW);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   697
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   698
        void simdPrefix(Register dst, Register nds, Register src, int sizePrefix, int opcodeEscapePrefix, boolean isRexW);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   699
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   700
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   701
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   702
    private class SSEEncoderImpl implements SIMDEncoder {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   703
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   704
        @Override
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   705
        public void simdPrefix(Register xreg, Register nds, AMD64Address adr, int sizePrefix, int opcodeEscapePrefix, boolean isRexW) {
52910
583fd71c47d6 8214023: Update Graal
dlong
parents: 52578
diff changeset
   706
            assert (!nds.isValid()) || nds.equals(xreg);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   707
            if (sizePrefix > 0) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   708
                emitByte(sizePrefix);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   709
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   710
            if (isRexW) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   711
                prefixq(adr, xreg);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   712
            } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   713
                prefix(adr, xreg);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   714
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   715
            if (opcodeEscapePrefix > 0xFF) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   716
                emitShort(opcodeEscapePrefix);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   717
            } else if (opcodeEscapePrefix > 0) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   718
                emitByte(opcodeEscapePrefix);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   719
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   720
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   721
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   722
        @Override
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   723
        public void simdPrefix(Register dst, Register nds, Register src, int sizePrefix, int opcodeEscapePrefix, boolean isRexW) {
52910
583fd71c47d6 8214023: Update Graal
dlong
parents: 52578
diff changeset
   724
            assert (!nds.isValid()) || nds.equals(dst) || nds.equals(src);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   725
            if (sizePrefix > 0) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   726
                emitByte(sizePrefix);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   727
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   728
            if (isRexW) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   729
                prefixq(dst, src);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   730
            } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   731
                prefix(dst, src);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   732
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   733
            if (opcodeEscapePrefix > 0xFF) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   734
                emitShort(opcodeEscapePrefix);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   735
            } else if (opcodeEscapePrefix > 0) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   736
                emitByte(opcodeEscapePrefix);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   737
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   738
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   739
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   740
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   741
    public static final class VEXPrefixConfig {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   742
        public static final int L128 = 0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   743
        public static final int L256 = 1;
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   744
        public static final int L512 = 2;
51736
42d99cb7f50f 8210478: Update Graal
iveresov
parents: 51436
diff changeset
   745
        public static final int LZ = 0;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   746
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   747
        public static final int W0 = 0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   748
        public static final int W1 = 1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   749
        public static final int WIG = 0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   750
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   751
        public static final int P_ = 0x0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   752
        public static final int P_66 = 0x1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   753
        public static final int P_F3 = 0x2;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   754
        public static final int P_F2 = 0x3;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   755
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   756
        public static final int M_0F = 0x1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   757
        public static final int M_0F38 = 0x2;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   758
        public static final int M_0F3A = 0x3;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   759
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   760
        private VEXPrefixConfig() {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   761
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   762
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   763
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   764
    private class VEXEncoderImpl implements SIMDEncoder {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   765
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   766
        private int sizePrefixToPP(int sizePrefix) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   767
            switch (sizePrefix) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   768
                case 0x66:
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   769
                    return P_66;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   770
                case 0xF2:
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   771
                    return P_F2;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   772
                case 0xF3:
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   773
                    return P_F3;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   774
                default:
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   775
                    return P_;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   776
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   777
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   778
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   779
        private int opcodeEscapePrefixToMMMMM(int opcodeEscapePrefix) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   780
            switch (opcodeEscapePrefix) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   781
                case 0x0F:
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   782
                    return M_0F;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   783
                case 0x380F:
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   784
                    return M_0F38;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   785
                case 0x3A0F:
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   786
                    return M_0F3A;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   787
                default:
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   788
                    return 0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   789
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   790
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   791
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   792
        @Override
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   793
        public void simdPrefix(Register reg, Register nds, AMD64Address rm, int sizePrefix, int opcodeEscapePrefix, boolean isRexW) {
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   794
            assert reg.encoding < 16 : "encoding out of range: " + reg.encoding;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   795
            assert nds.encoding < 16 : "encoding out of range: " + nds.encoding;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   796
            emitVEX(L128, sizePrefixToPP(sizePrefix), opcodeEscapePrefixToMMMMM(opcodeEscapePrefix), isRexW ? W1 : W0, getRXB(reg, rm), nds.isValid() ? nds.encoding : 0, true);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   797
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   798
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   799
        @Override
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   800
        public void simdPrefix(Register dst, Register nds, Register src, int sizePrefix, int opcodeEscapePrefix, boolean isRexW) {
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   801
            assert dst.encoding < 16 : "encoding out of range: " + dst.encoding;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   802
            assert src.encoding < 16 : "encoding out of range: " + src.encoding;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   803
            assert nds.encoding < 16 : "encoding out of range: " + nds.encoding;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   804
            emitVEX(L128, sizePrefixToPP(sizePrefix), opcodeEscapePrefixToMMMMM(opcodeEscapePrefix), isRexW ? W1 : W0, getRXB(dst, src), nds.isValid() ? nds.encoding : 0, true);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   805
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   806
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   807
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   808
    protected final void simdPrefix(Register xreg, Register nds, AMD64Address adr, OperandSize size, int overriddenSizePrefix, int opcodeEscapePrefix, boolean isRexW) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   809
        simdEncoder.simdPrefix(xreg, nds, adr, overriddenSizePrefix != 0 ? overriddenSizePrefix : size.sizePrefix, opcodeEscapePrefix, isRexW);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   810
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   811
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   812
    protected final void simdPrefix(Register xreg, Register nds, AMD64Address adr, OperandSize size, int opcodeEscapePrefix, boolean isRexW) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   813
        simdEncoder.simdPrefix(xreg, nds, adr, size.sizePrefix, opcodeEscapePrefix, isRexW);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   814
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   815
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   816
    protected final void simdPrefix(Register dst, Register nds, Register src, OperandSize size, int overriddenSizePrefix, int opcodeEscapePrefix, boolean isRexW) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   817
        simdEncoder.simdPrefix(dst, nds, src, overriddenSizePrefix != 0 ? overriddenSizePrefix : size.sizePrefix, opcodeEscapePrefix, isRexW);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   818
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   819
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   820
    protected final void simdPrefix(Register dst, Register nds, Register src, OperandSize size, int opcodeEscapePrefix, boolean isRexW) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   821
        simdEncoder.simdPrefix(dst, nds, src, size.sizePrefix, opcodeEscapePrefix, isRexW);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   822
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   823
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   824
 // @formatter:off
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   825
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   826
 // Instruction Format and VEX illustrated below (optional []):
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   827
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   828
 // #of bytes:    2,3      1       1       1       1,2,4       1
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   829
 // [Prefixes]    VEX   OpCode   ModR/M  [SIB]   [Disp8*N] [Immediate]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   830
 //                                             [Disp16,32]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   831
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   832
 // VEX: 0xC4 | P1 | P2
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   833
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   834
 //     7   6   5   4   3   2   1   0
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   835
 // P1  R   X   B   m   m   m   m   m      P[ 7:0]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   836
 // P2  W   v   v   v   v   L   p   p      P[15:8]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   837
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   838
 // VEX: 0xC5 | B1
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   839
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   840
 //     7   6   5   4   3   2   1   0
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   841
 // P1  R   v   v   v   v   L   p   p      P[7:0]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   842
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   843
 // Figure. Bit Field Layout of the VEX Prefix
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   844
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   845
 // Table. VEX Prefix Bit Field Functional Grouping
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   846
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   847
 // Notation        Bit field Group        Position        Comment
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   848
 // ----------  -------------------------  --------  -------------------
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   849
 // VEX.RXB     Next-8 register specifier  P[7:5]    Combine with ModR/M.reg, ModR/M.rm (base, index/vidx).
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   850
 // VEX.R       REX.R inverse              P[7]      Combine with EVEX.R and ModR/M.reg.
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   851
 // VEX.X       REX.X inverse              P[6]      Combine with EVEX.B and ModR/M.rm, when SIB/VSIB absent.
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   852
 // VEX.B       REX.B inverse              P[5]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   853
 // VEX.mmmmmm  0F, 0F_38, 0F_3A encoding  P[4:0]    b01/0x0F, b10/0F_38, b11/0F_3A (all other reserved)
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   854
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   855
 // VEX.W       Opcode specific            P[15]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   856
 // VEX.vvvv    A register specifier       P[14:11]  In inverse form, b1111 if not used.
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   857
 //                                        P[6:3]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   858
 // VEX.L       Vector length/RC           P[10]     b0/scalar or 128b vec, b1/256b vec.
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   859
 //                                        P[2]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   860
 // VEX.pp      Compressed legacy prefix   P[9:8]    b00/None, b01/0x66, b10/0xF3, b11/0xF2
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   861
 //                                        P[1:0]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   862
 // @formatter:on
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   863
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   864
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   865
     * Low-level function to encode and emit the VEX prefix.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   866
     * <p>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   867
     * 2 byte form: [1100 0101] [R vvvv L pp]<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   868
     * 3 byte form: [1100 0100] [RXB m-mmmm] [W vvvv L pp]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   869
     * <p>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   870
     * The RXB and vvvv fields are stored in 1's complement in the prefix encoding. This function
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   871
     * performs the 1s complement conversion, the caller is expected to pass plain unencoded
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   872
     * arguments.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   873
     * <p>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   874
     * The pp field encodes an extension to the opcode:<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   875
     * 00: no extension<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   876
     * 01: 66<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   877
     * 10: F3<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   878
     * 11: F2
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   879
     * <p>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   880
     * The m-mmmm field encodes the leading bytes of the opcode:<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   881
     * 00001: implied 0F leading opcode byte (default in 2-byte encoding)<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   882
     * 00010: implied 0F 38 leading opcode bytes<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   883
     * 00011: implied 0F 3A leading opcode bytes
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   884
     * <p>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   885
     * This function automatically chooses the 2 or 3 byte encoding, based on the XBW flags and the
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   886
     * m-mmmm field.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   887
     */
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   888
    protected final void emitVEX(int l, int pp, int mmmmm, int w, int rxb, int vvvv, boolean checkAVX) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   889
        assert !checkAVX || ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX) : "emitting VEX prefix on a CPU without AVX support";
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   890
51736
42d99cb7f50f 8210478: Update Graal
iveresov
parents: 51436
diff changeset
   891
        assert l == L128 || l == L256 : "invalid value for VEX.L";
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   892
        assert pp == P_ || pp == P_66 || pp == P_F3 || pp == P_F2 : "invalid value for VEX.pp";
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   893
        assert mmmmm == M_0F || mmmmm == M_0F38 || mmmmm == M_0F3A : "invalid value for VEX.m-mmmm";
51736
42d99cb7f50f 8210478: Update Graal
iveresov
parents: 51436
diff changeset
   894
        assert w == W0 || w == W1 : "invalid value for VEX.W";
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   895
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   896
        assert (rxb & 0x07) == rxb : "invalid value for VEX.RXB";
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   897
        assert (vvvv & 0x0F) == vvvv : "invalid value for VEX.vvvv";
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   898
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   899
        int rxb1s = rxb ^ 0x07;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   900
        int vvvv1s = vvvv ^ 0x0F;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   901
        if ((rxb & 0x03) == 0 && w == WIG && mmmmm == M_0F) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   902
            // 2 byte encoding
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   903
            int byte2 = 0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   904
            byte2 |= (rxb1s & 0x04) << 5;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   905
            byte2 |= vvvv1s << 3;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   906
            byte2 |= l << 2;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   907
            byte2 |= pp;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   908
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   909
            emitByte(Prefix.VEX2);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   910
            emitByte(byte2);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   911
        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   912
            // 3 byte encoding
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   913
            int byte2 = 0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   914
            byte2 = (rxb1s & 0x07) << 5;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   915
            byte2 |= mmmmm;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   916
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   917
            int byte3 = 0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   918
            byte3 |= w << 7;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   919
            byte3 |= vvvv1s << 3;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   920
            byte3 |= l << 2;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   921
            byte3 |= pp;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   922
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   923
            emitByte(Prefix.VEX3);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   924
            emitByte(byte2);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   925
            emitByte(byte3);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   926
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   927
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   928
51736
42d99cb7f50f 8210478: Update Graal
iveresov
parents: 51436
diff changeset
   929
    public static int getLFlag(AVXSize size) {
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   930
        switch (size) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   931
            case XMM:
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   932
                return L128;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   933
            case YMM:
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   934
                return L256;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   935
            case ZMM:
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   936
                return L512;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   937
            default:
51736
42d99cb7f50f 8210478: Update Graal
iveresov
parents: 51436
diff changeset
   938
                return LZ;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   939
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   940
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   941
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   942
    public static boolean isAVX512Register(Register reg) {
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   943
        return reg != null && reg.isValid() && AMD64.XMM.equals(reg.getRegisterCategory()) && reg.encoding > 15;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   944
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   945
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   946
    public final boolean vexPrefix(Register dst, Register nds, Register src, AVXSize size, int pp, int mmmmm, int w, int wEvex, boolean checkAVX) {
59095
03fbcd06b4c0 8233841: Update Graal
dlong
parents: 58299
diff changeset
   947
        if (isAVX512Register(dst) || isAVX512Register(nds) || isAVX512Register(src) || size == AVXSize.ZMM) {
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   948
            evexPrefix(dst, Register.None, nds, src, size, pp, mmmmm, wEvex, Z0, B0);
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   949
            return true;
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   950
        }
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
   951
        emitVEX(getLFlag(size), pp, mmmmm, w, getRXB(dst, src), nds.isValid() ? nds.encoding() : 0, checkAVX);
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   952
        return false;
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   953
    }
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   954
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   955
    public final boolean vexPrefix(Register dst, Register nds, AMD64Address src, AVXSize size, int pp, int mmmmm, int w, int wEvex, boolean checkAVX) {
59095
03fbcd06b4c0 8233841: Update Graal
dlong
parents: 58299
diff changeset
   956
        if (isAVX512Register(dst) || isAVX512Register(nds) || size == AVXSize.ZMM) {
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   957
            evexPrefix(dst, Register.None, nds, src, size, pp, mmmmm, wEvex, Z0, B0);
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   958
            return true;
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   959
        }
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   960
        emitVEX(getLFlag(size), pp, mmmmm, w, getRXB(dst, src), nds.isValid() ? nds.encoding() : 0, checkAVX);
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   961
        return false;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   962
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   963
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   964
    protected static final class EVEXPrefixConfig {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   965
        public static final int Z0 = 0x0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   966
        public static final int Z1 = 0x1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   967
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   968
        public static final int B0 = 0x0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   969
        public static final int B1 = 0x1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   970
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   971
        private EVEXPrefixConfig() {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   972
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   973
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   974
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   975
    private static final int NOT_SUPPORTED_VECTOR_LENGTH = -1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   976
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   977
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   978
     * EVEX-encoded instructions use a compressed displacement scheme by multiplying disp8 with a
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   979
     * scaling factor N depending on the tuple type and the vector length.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   980
     *
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   981
     * Reference: Intel Software Developer's Manual Volume 2, Section 2.6.5
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   982
     */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   983
    protected enum EVEXTuple {
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
   984
        INVALID(NOT_SUPPORTED_VECTOR_LENGTH, NOT_SUPPORTED_VECTOR_LENGTH, NOT_SUPPORTED_VECTOR_LENGTH),
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   985
        FV_NO_BROADCAST_32BIT(16, 32, 64),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   986
        FV_BROADCAST_32BIT(4, 4, 4),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   987
        FV_NO_BROADCAST_64BIT(16, 32, 64),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   988
        FV_BROADCAST_64BIT(8, 8, 8),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   989
        HV_NO_BROADCAST_32BIT(8, 16, 32),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   990
        HV_BROADCAST_32BIT(4, 4, 4),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   991
        FVM(16, 32, 64),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   992
        T1S_8BIT(1, 1, 1),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   993
        T1S_16BIT(2, 2, 2),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   994
        T1S_32BIT(4, 4, 4),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   995
        T1S_64BIT(8, 8, 8),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   996
        T1F_32BIT(4, 4, 4),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   997
        T1F_64BIT(8, 8, 8),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   998
        T2_32BIT(8, 8, 8),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   999
        T2_64BIT(NOT_SUPPORTED_VECTOR_LENGTH, 16, 16),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1000
        T4_32BIT(NOT_SUPPORTED_VECTOR_LENGTH, 16, 16),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1001
        T4_64BIT(NOT_SUPPORTED_VECTOR_LENGTH, NOT_SUPPORTED_VECTOR_LENGTH, 32),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1002
        T8_32BIT(NOT_SUPPORTED_VECTOR_LENGTH, NOT_SUPPORTED_VECTOR_LENGTH, 32),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1003
        HVM(8, 16, 32),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1004
        QVM(4, 8, 16),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1005
        OVM(2, 4, 8),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1006
        M128(16, 16, 16),
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1007
        DUP(8, 32, 64);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1008
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1009
        private final int scalingFactorVL128;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1010
        private final int scalingFactorVL256;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1011
        private final int scalingFactorVL512;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1012
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1013
        EVEXTuple(int scalingFactorVL128, int scalingFactorVL256, int scalingFactorVL512) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1014
            this.scalingFactorVL128 = scalingFactorVL128;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1015
            this.scalingFactorVL256 = scalingFactorVL256;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1016
            this.scalingFactorVL512 = scalingFactorVL512;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1017
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1018
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1019
        private static int verifyScalingFactor(int scalingFactor) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1020
            if (scalingFactor == NOT_SUPPORTED_VECTOR_LENGTH) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1021
                throw GraalError.shouldNotReachHere("Invalid scaling factor.");
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1022
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1023
            return scalingFactor;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1024
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1025
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1026
        public int getDisp8ScalingFactor(AVXSize size) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1027
            switch (size) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1028
                case XMM:
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1029
                    return verifyScalingFactor(scalingFactorVL128);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1030
                case YMM:
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1031
                    return verifyScalingFactor(scalingFactorVL256);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1032
                case ZMM:
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1033
                    return verifyScalingFactor(scalingFactorVL512);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1034
                default:
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1035
                    throw GraalError.shouldNotReachHere("Unsupported vector size.");
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1036
            }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1037
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1038
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1039
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1040
 // @formatter:off
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1041
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1042
 // Instruction Format and EVEX illustrated below (optional []):
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1043
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1044
 // #of bytes:      4       1       1       1       1,2,4       1
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1045
 // [Prefixes]    EVEX   OpCode   ModR/M  [SIB]   [Disp8*N] [Immediate]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1046
 //                                              [Disp16,32]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1047
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1048
 // The EVEX prefix is a 4-byte prefix, with the first two bytes derived from unused encoding
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1049
 // form of the 32-bit-mode-only BOUND instruction. The layout of the EVEX prefix is shown in
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1050
 // the figure below. The first byte must be 0x62, followed by three pay-load bytes, denoted
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1051
 // as P1, P2, and P3 individually or collectively as P[23:0] (see below).
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1052
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1053
 // EVEX: 0x62 | P1 | P2 | P3
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1054
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1055
 //     7   6   5   4   3   2   1   0
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1056
 // P1  R   X   B   R'  0   0   m   m      P[ 7: 0]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1057
 // P2  W   v   v   v   v   1   p   p      P[15: 8]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1058
 // P3  z   L'  L   b   V'  a   a   a      P[23:16]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1059
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1060
 // Figure. Bit Field Layout of the EVEX Prefix
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1061
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1062
 // Table. EVEX Prefix Bit Field Functional Grouping
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1063
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1064
 // Notation        Bit field Group        Position        Comment
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1065
 // ---------  --------------------------  --------  -----------------------
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1066
 // EVEX.RXB   Next-8 register specifier   P[7:5]    Combine with ModR/M.reg, ModR/M.rm (base, index/vidx).
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1067
 // EVEX.X     High-16 register specifier  P[6]      Combine with EVEX.B and ModR/M.rm, when SIB/VSIB absent.
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1068
 // EVEX.R'    High-16 register specifier  P[4]      Combine with EVEX.R and ModR/M.reg.
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1069
 // --         Reserved                    P[3:2]    Must be 0.
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1070
 // EVEX.mm    Compressed legacy escape    P[1:0]    Identical to low two bits of VEX.mmmmm.
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1071
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1072
 // EVEX.W     Osize promotion/Opcode ext  P[15]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1073
 // EVEX.vvvv  NDS register specifier      P[14:11]  Same as VEX.vvvv.
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1074
 // --         Fixed Value                 P[10]     Must be 1.
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1075
 // EVEX.pp    Compressed legacy prefix    P[9:8]    Identical to VEX.pp.
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1076
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1077
 // EVEX.z     Zeroing/Merging             P[23]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1078
 // EVEX.L'L   Vector length/RC            P[22:21]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1079
 // EVEX.b     Broadcast/RC/SAE Context    P[20]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1080
 // EVEX.V'    High-16 NDS/VIDX register   P[19]     Combine with EVEX.vvvv or VSIB when present.
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1081
 // EVEX.aaa   Embedded opmask register    P[18:16]
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1082
 //
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1083
 // @formatter:on
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1084
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1085
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1086
     * Low-level function to encode and emit the EVEX prefix.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1087
     * <p>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1088
     * 62 [0 1 1 0 0 0 1 0]<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1089
     * P1 [R X B R'0 0 m m]<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1090
     * P2 [W v v v v 1 p p]<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1091
     * P3 [z L'L b V'a a a]
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1092
     * <p>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1093
     * The pp field encodes an extension to the opcode:<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1094
     * 00: no extension<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1095
     * 01: 66<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1096
     * 10: F3<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1097
     * 11: F2
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1098
     * <p>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1099
     * The mm field encodes the leading bytes of the opcode:<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1100
     * 01: implied 0F leading opcode byte<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1101
     * 10: implied 0F 38 leading opcode bytes<br>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1102
     * 11: implied 0F 3A leading opcode bytes
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1103
     * <p>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1104
     * The z field encodes the merging mode (merge or zero).
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1105
     * <p>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1106
     * The b field encodes the source broadcast or data rounding modes.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1107
     * <p>
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1108
     * The aaa field encodes the operand mask register.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1109
     */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1110
    private void emitEVEX(int l, int pp, int mm, int w, int rxb, int reg, int vvvvv, int z, int b, int aaa) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1111
        assert ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX512F) : "emitting EVEX prefix on a CPU without AVX512 support";
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1112
51736
42d99cb7f50f 8210478: Update Graal
iveresov
parents: 51436
diff changeset
  1113
        assert l == L128 || l == L256 || l == L512 : "invalid value for EVEX.L'L";
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1114
        assert pp == P_ || pp == P_66 || pp == P_F3 || pp == P_F2 : "invalid value for EVEX.pp";
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1115
        assert mm == M_0F || mm == M_0F38 || mm == M_0F3A : "invalid value for EVEX.mm";
51736
42d99cb7f50f 8210478: Update Graal
iveresov
parents: 51436
diff changeset
  1116
        assert w == W0 || w == W1 : "invalid value for EVEX.W";
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1117
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1118
        assert (rxb & 0x07) == rxb : "invalid value for EVEX.RXB";
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1119
        assert (reg & 0x1F) == reg : "invalid value for EVEX.R'";
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1120
        assert (vvvvv & 0x1F) == vvvvv : "invalid value for EVEX.V'vvvv";
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1121
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1122
        assert z == Z0 || z == Z1 : "invalid value for EVEX.z";
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1123
        assert b == B0 || b == B1 : "invalid value for EVEX.b";
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1124
        assert (aaa & 0x07) == aaa : "invalid value for EVEX.aaa";
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1125
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1126
        emitByte(Prefix.EVEX);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1127
        int p1 = 0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1128
        p1 |= ((rxb ^ 0x07) & 0x07) << 5;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1129
        p1 |= reg < 16 ? 0x10 : 0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1130
        p1 |= mm;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1131
        emitByte(p1);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1132
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1133
        int p2 = 0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1134
        p2 |= w << 7;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1135
        p2 |= ((vvvvv ^ 0x0F) & 0x0F) << 3;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1136
        p2 |= 0x04;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1137
        p2 |= pp;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1138
        emitByte(p2);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1139
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1140
        int p3 = 0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1141
        p3 |= z << 7;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1142
        p3 |= l << 5;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1143
        p3 |= b << 4;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1144
        p3 |= vvvvv < 16 ? 0x08 : 0;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1145
        p3 |= aaa;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1146
        emitByte(p3);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1147
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1148
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1149
    /**
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1150
     * Get RXB bits for register-register instructions in EVEX-encoding, where ModRM.rm contains a
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1151
     * register index. The R bit extends the ModRM.reg field and the X and B bits extends the
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1152
     * ModRM.rm field.
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1153
     */
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1154
    private static int getRXBForEVEX(Register reg, Register rm) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1155
        int rxb = (reg == null ? 0 : reg.encoding & 0x08) >> 1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1156
        rxb |= (rm == null ? 0 : rm.encoding & 0x018) >> 3;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1157
        return rxb;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1158
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1159
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1160
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1161
     * Helper method for emitting EVEX prefix in the form of RRRR.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1162
     */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1163
    protected final void evexPrefix(Register dst, Register mask, Register nds, Register src, AVXSize size, int pp, int mm, int w, int z, int b) {
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1164
        assert !mask.isValid() || inRC(MASK, mask);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1165
        emitEVEX(getLFlag(size), pp, mm, w, getRXBForEVEX(dst, src), dst.encoding, nds.isValid() ? nds.encoding() : 0, z, b, mask.isValid() ? mask.encoding : 0);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1166
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1167
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1168
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1169
     * Helper method for emitting EVEX prefix in the form of RRRM. Because the memory addressing in
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1170
     * EVEX-encoded instructions employ a compressed displacement scheme when using disp8 form, the
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1171
     * user of this API should make sure to encode the operands using
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 54084
diff changeset
  1172
     * {@link #emitOperandHelper(Register, AMD64Address, int, int)}.
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1173
     */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1174
    protected final void evexPrefix(Register dst, Register mask, Register nds, AMD64Address src, AVXSize size, int pp, int mm, int w, int z, int b) {
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51736
diff changeset
  1175
        assert !mask.isValid() || inRC(MASK, mask);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1176
        emitEVEX(getLFlag(size), pp, mm, w, getRXB(dst, src), dst.encoding, nds.isValid() ? nds.encoding() : 0, z, b, mask.isValid() ? mask.encoding : 0);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1177
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1178
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
  1179
}