1 /*
  2  * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 package jdk.internal.foreign.abi.x64;
 26 
 27 import jdk.internal.foreign.abi.ABIDescriptor;
 28 import jdk.internal.foreign.abi.Architecture;
 29 import jdk.internal.foreign.abi.VMStorage;
 30 
 31 import java.util.stream.IntStream;
 32 
 33 public class X86_64Architecture implements Architecture {
 34     public static final Architecture INSTANCE = new X86_64Architecture();
 35     private static final int INTEGER_REG_SIZE = 8; // bytes
 36     private static final int VECTOR_REG_SIZE = 16; // size of XMM register
 37     private static final int X87_REG_SIZE = 16;
 38     private static final int STACK_SLOT_SIZE = 8;
 39 
 40     @Override
 41     public boolean isStackType(int cls) {
 42         return cls == StorageClasses.STACK;
 43     }
 44 
 45     @Override
 46     public int typeSize(int cls) {
 47         switch (cls) {
 48             case StorageClasses.INTEGER: return INTEGER_REG_SIZE;
 49             case StorageClasses.VECTOR: return VECTOR_REG_SIZE;
 50             case StorageClasses.X87: return X87_REG_SIZE;
 51             case StorageClasses.STACK: return STACK_SLOT_SIZE;
 52         }
 53 
 54         throw new IllegalArgumentException("Invalid Storage Class: " +cls);
 55     }
 56 
 57     @Override
 58     public int stackType() {
 59         return StorageClasses.STACK;
 60     }
 61 
 62     public interface StorageClasses {
 63         int INTEGER = 0;
 64         int VECTOR = 1;
 65         int X87 = 2;
 66         int STACK = 3;
 67     }
 68 
 69     public static final VMStorage rax = integerRegister(0, "rax");
 70     public static final VMStorage rcx = integerRegister(1, "rcx");
 71     public static final VMStorage rdx = integerRegister(2, "rdx");
 72     public static final VMStorage rbx = integerRegister(3, "rbx");
 73     public static final VMStorage rsp = integerRegister(4, "rsp");
 74     public static final VMStorage rbp = integerRegister(5, "rbp");
 75     public static final VMStorage rsi = integerRegister(6, "rsi");
 76     public static final VMStorage rdi = integerRegister(7, "rdi");
 77     public static final VMStorage r8 =  integerRegister(8, "r8");
 78     public static final VMStorage r9 =  integerRegister(9, "r9");
 79     public static final VMStorage r10 = integerRegister(10, "r10");
 80     public static final VMStorage r11 = integerRegister(11, "r11");
 81     public static final VMStorage r12 = integerRegister(12, "r12");
 82     public static final VMStorage r13 = integerRegister(13, "r13");
 83     public static final VMStorage r14 = integerRegister(14, "r14");
 84     public static final VMStorage r15 = integerRegister(15, "r15");
 85 
 86     public static final VMStorage xmm0 =  vectorRegister(0, "xmm0");
 87     public static final VMStorage xmm1 =  vectorRegister(1, "xmm1");
 88     public static final VMStorage xmm2 =  vectorRegister(2, "xmm2");
 89     public static final VMStorage xmm3 =  vectorRegister(3, "xmm3");
 90     public static final VMStorage xmm4 =  vectorRegister(4, "xmm4");
 91     public static final VMStorage xmm5 =  vectorRegister(5, "xmm5");
 92     public static final VMStorage xmm6 =  vectorRegister(6, "xmm6");
 93     public static final VMStorage xmm7 =  vectorRegister(7, "xmm7");
 94     public static final VMStorage xmm8 =  vectorRegister(8, "xmm8");
 95     public static final VMStorage xmm9 =  vectorRegister(9, "xmm9");
 96     public static final VMStorage xmm10 = vectorRegister(10, "xmm10");
 97     public static final VMStorage xmm11 = vectorRegister(11, "xmm11");
 98     public static final VMStorage xmm12 = vectorRegister(12, "xmm12");
 99     public static final VMStorage xmm13 = vectorRegister(13, "xmm13");
100     public static final VMStorage xmm14 = vectorRegister(14, "xmm14");
101     public static final VMStorage xmm15 = vectorRegister(15, "xmm15");
102     public static final VMStorage xmm16 = vectorRegister(16, "xmm16");
103     public static final VMStorage xmm17 = vectorRegister(17, "xmm17");
104     public static final VMStorage xmm18 = vectorRegister(18, "xmm18");
105     public static final VMStorage xmm19 = vectorRegister(19, "xmm19");
106     public static final VMStorage xmm20 = vectorRegister(20, "xmm20");
107     public static final VMStorage xmm21 = vectorRegister(21, "xmm21");
108     public static final VMStorage xmm22 = vectorRegister(22, "xmm22");
109     public static final VMStorage xmm23 = vectorRegister(23, "xmm23");
110     public static final VMStorage xmm24 = vectorRegister(24, "xmm24");
111     public static final VMStorage xmm25 = vectorRegister(25, "xmm25");
112     public static final VMStorage xmm26 = vectorRegister(26, "xmm26");
113     public static final VMStorage xmm27 = vectorRegister(27, "xmm27");
114     public static final VMStorage xmm28 = vectorRegister(28, "xmm28");
115     public static final VMStorage xmm29 = vectorRegister(29, "xmm29");
116     public static final VMStorage xmm30 = vectorRegister(30, "xmm30");
117     public static final VMStorage xmm31 = vectorRegister(31, "xmm31");
118 
119     private static VMStorage integerRegister(int index, String debugName) {
120         return new VMStorage(StorageClasses.INTEGER, index, debugName);
121     }
122 
123     private static VMStorage vectorRegister(int index, String debugName) {
124         return new VMStorage(StorageClasses.VECTOR, index, debugName);
125     }
126 
127     public static VMStorage stackStorage(int index) {
128         return new VMStorage(StorageClasses.STACK, index, "Stack@" + index);
129     }
130 
131     public static VMStorage x87Storage(int index) {
132         return new VMStorage(StorageClasses.X87, index, "X87(" + index + ")");
133     }
134 
135     public static ABIDescriptor abiFor(VMStorage[] inputIntRegs, VMStorage[] inputVectorRegs, VMStorage[] outputIntRegs,
136                                        VMStorage[] outputVectorRegs, int numX87Outputs, VMStorage[] volatileIntRegs,
137                                        VMStorage[] volatileVectorRegs, int stackAlignment, int shadowSpace) {
138         return new ABIDescriptor(
139             INSTANCE,
140             new VMStorage[][] {
141                 inputIntRegs,
142                 inputVectorRegs,
143             },
144             new VMStorage[][] {
145                 outputIntRegs,
146                 outputVectorRegs,
147                 IntStream.range(0, numX87Outputs).mapToObj(X86_64Architecture::x87Storage).toArray(VMStorage[]::new)
148             },
149             new VMStorage[][] {
150                 volatileIntRegs,
151                 volatileVectorRegs,
152             },
153             stackAlignment,
154             shadowSpace
155         );
156     }
157 
158 }