001/*
002 * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package jdk.internal.jvmci.sparc;
024
025import static jdk.internal.jvmci.code.MemoryBarriers.*;
026
027import java.nio.*;
028import java.util.*;
029
030import jdk.internal.jvmci.code.*;
031import jdk.internal.jvmci.code.Register.*;
032import jdk.internal.jvmci.meta.*;
033
034/**
035 * Represents the SPARC architecture.
036 */
037public class SPARC extends Architecture {
038
039    public static final RegisterCategory CPU = new RegisterCategory("CPU");
040
041    // General purpose registers
042    public static final Register r0 = new Register(0, 0, "g0", CPU);
043    public static final Register r1 = new Register(1, 1, "g1", CPU);
044    public static final Register r2 = new Register(2, 2, "g2", CPU);
045    public static final Register r3 = new Register(3, 3, "g3", CPU);
046    public static final Register r4 = new Register(4, 4, "g4", CPU);
047    public static final Register r5 = new Register(5, 5, "g5", CPU);
048    public static final Register r6 = new Register(6, 6, "g6", CPU);
049    public static final Register r7 = new Register(7, 7, "g7", CPU);
050
051    public static final Register r8 = new Register(8, 8, "o0", CPU);
052    public static final Register r9 = new Register(9, 9, "o1", CPU);
053    public static final Register r10 = new Register(10, 10, "o2", CPU);
054    public static final Register r11 = new Register(11, 11, "o3", CPU);
055    public static final Register r12 = new Register(12, 12, "o4", CPU);
056    public static final Register r13 = new Register(13, 13, "o5", CPU);
057    public static final Register r14 = new Register(14, 14, "o6", CPU);
058    public static final Register r15 = new Register(15, 15, "o7", CPU);
059
060    public static final Register r16 = new Register(16, 16, "l0", CPU);
061    public static final Register r17 = new Register(17, 17, "l1", CPU);
062    public static final Register r18 = new Register(18, 18, "l2", CPU);
063    public static final Register r19 = new Register(19, 19, "l3", CPU);
064    public static final Register r20 = new Register(20, 20, "l4", CPU);
065    public static final Register r21 = new Register(21, 21, "l5", CPU);
066    public static final Register r22 = new Register(22, 22, "l6", CPU);
067    public static final Register r23 = new Register(23, 23, "l7", CPU);
068
069    public static final Register r24 = new Register(24, 24, "i0", CPU);
070    public static final Register r25 = new Register(25, 25, "i1", CPU);
071    public static final Register r26 = new Register(26, 26, "i2", CPU);
072    public static final Register r27 = new Register(27, 27, "i3", CPU);
073    public static final Register r28 = new Register(28, 28, "i4", CPU);
074    public static final Register r29 = new Register(29, 29, "i5", CPU);
075    public static final Register r30 = new Register(30, 30, "i6", CPU);
076    public static final Register r31 = new Register(31, 31, "i7", CPU);
077
078    public static final Register g0 = r0;
079    public static final Register g1 = r1;
080    public static final Register g2 = r2;
081    public static final Register g3 = r3;
082    public static final Register g4 = r4;
083    public static final Register g5 = r5;
084    public static final Register g6 = r6;
085    public static final Register g7 = r7;
086
087    public static final Register o0 = r8;
088    public static final Register o1 = r9;
089    public static final Register o2 = r10;
090    public static final Register o3 = r11;
091    public static final Register o4 = r12;
092    public static final Register o5 = r13;
093    public static final Register o6 = r14;
094    public static final Register o7 = r15;
095
096    public static final Register l0 = r16;
097    public static final Register l1 = r17;
098    public static final Register l2 = r18;
099    public static final Register l3 = r19;
100    public static final Register l4 = r20;
101    public static final Register l5 = r21;
102    public static final Register l6 = r22;
103    public static final Register l7 = r23;
104
105    public static final Register i0 = r24;
106    public static final Register i1 = r25;
107    public static final Register i2 = r26;
108    public static final Register i3 = r27;
109    public static final Register i4 = r28;
110    public static final Register i5 = r29;
111    public static final Register i6 = r30;
112    public static final Register i7 = r31;
113
114    public static final Register sp = o6;
115    public static final Register fp = i6;
116
117    // @formatter:off
118    public static final Register[] cpuRegisters = {
119        r0,  r1,  r2,  r3,  r4,  r5,  r6,  r7,
120        r8,  r9,  r10, r11, r12, r13, r14, r15,
121        r16, r17, r18, r19, r20, r21, r22, r23,
122        r24, r25, r26, r27, r28, r29, r30, r31
123    };
124    // @formatter:on
125
126    public static final RegisterCategory FPUs = new RegisterCategory("FPUs", cpuRegisters.length);
127    public static final RegisterCategory FPUd = new RegisterCategory("FPUd", cpuRegisters.length + 32);
128
129    // Floating point registers
130    public static final Register f0 = new Register(32, 0, "f0", FPUs);
131    public static final Register f1 = new Register(33, 1, "f1", FPUs);
132    public static final Register f2 = new Register(34, 2, "f2", FPUs);
133    public static final Register f3 = new Register(35, 3, "f3", FPUs);
134    public static final Register f4 = new Register(36, 4, "f4", FPUs);
135    public static final Register f5 = new Register(37, 5, "f5", FPUs);
136    public static final Register f6 = new Register(38, 6, "f6", FPUs);
137    public static final Register f7 = new Register(39, 7, "f7", FPUs);
138
139    public static final Register f8 = new Register(40, 8, "f8", FPUs);
140    public static final Register f9 = new Register(41, 9, "f9", FPUs);
141    public static final Register f10 = new Register(42, 10, "f10", FPUs);
142    public static final Register f11 = new Register(43, 11, "f11", FPUs);
143    public static final Register f12 = new Register(44, 12, "f12", FPUs);
144    public static final Register f13 = new Register(45, 13, "f13", FPUs);
145    public static final Register f14 = new Register(46, 14, "f14", FPUs);
146    public static final Register f15 = new Register(47, 15, "f15", FPUs);
147
148    public static final Register f16 = new Register(48, 16, "f16", FPUs);
149    public static final Register f17 = new Register(49, 17, "f17", FPUs);
150    public static final Register f18 = new Register(50, 18, "f18", FPUs);
151    public static final Register f19 = new Register(51, 19, "f19", FPUs);
152    public static final Register f20 = new Register(52, 20, "f20", FPUs);
153    public static final Register f21 = new Register(53, 21, "f21", FPUs);
154    public static final Register f22 = new Register(54, 22, "f22", FPUs);
155    public static final Register f23 = new Register(55, 23, "f23", FPUs);
156
157    public static final Register f24 = new Register(56, 24, "f24", FPUs);
158    public static final Register f25 = new Register(57, 25, "f25", FPUs);
159    public static final Register f26 = new Register(58, 26, "f26", FPUs);
160    public static final Register f27 = new Register(59, 27, "f27", FPUs);
161    public static final Register f28 = new Register(60, 28, "f28", FPUs);
162    public static final Register f29 = new Register(61, 29, "f29", FPUs);
163    public static final Register f30 = new Register(62, 30, "f30", FPUs);
164    public static final Register f31 = new Register(63, 31, "f31", FPUs);
165
166    public static final Register d0 = new Register(32, getDoubleEncoding(0), "d0", FPUs);
167    public static final Register d2 = new Register(34, getDoubleEncoding(2), "d2", FPUs);
168    public static final Register d4 = new Register(36, getDoubleEncoding(4), "d4", FPUs);
169    public static final Register d6 = new Register(38, getDoubleEncoding(6), "d6", FPUs);
170    public static final Register d8 = new Register(40, getDoubleEncoding(8), "d8", FPUs);
171    public static final Register d10 = new Register(42, getDoubleEncoding(10), "d10", FPUs);
172    public static final Register d12 = new Register(44, getDoubleEncoding(12), "d12", FPUs);
173    public static final Register d14 = new Register(46, getDoubleEncoding(14), "d14", FPUs);
174
175    public static final Register d16 = new Register(48, getDoubleEncoding(16), "d16", FPUs);
176    public static final Register d18 = new Register(50, getDoubleEncoding(18), "d18", FPUs);
177    public static final Register d20 = new Register(52, getDoubleEncoding(20), "d20", FPUs);
178    public static final Register d22 = new Register(54, getDoubleEncoding(22), "d22", FPUs);
179    public static final Register d24 = new Register(56, getDoubleEncoding(24), "d24", FPUs);
180    public static final Register d26 = new Register(58, getDoubleEncoding(26), "d26", FPUs);
181    public static final Register d28 = new Register(60, getDoubleEncoding(28), "d28", FPUs);
182    public static final Register d30 = new Register(62, getDoubleEncoding(28), "d28", FPUs);
183
184    public static final Register d32 = new Register(64, getDoubleEncoding(32), "d32", FPUd);
185    public static final Register d34 = new Register(65, getDoubleEncoding(34), "d34", FPUd);
186    public static final Register d36 = new Register(66, getDoubleEncoding(36), "d36", FPUd);
187    public static final Register d38 = new Register(67, getDoubleEncoding(38), "d38", FPUd);
188    public static final Register d40 = new Register(68, getDoubleEncoding(40), "d40", FPUd);
189    public static final Register d42 = new Register(69, getDoubleEncoding(42), "d42", FPUd);
190    public static final Register d44 = new Register(70, getDoubleEncoding(44), "d44", FPUd);
191    public static final Register d46 = new Register(71, getDoubleEncoding(46), "d46", FPUd);
192
193    public static final Register d48 = new Register(72, getDoubleEncoding(48), "d48", FPUd);
194    public static final Register d50 = new Register(73, getDoubleEncoding(50), "d50", FPUd);
195    public static final Register d52 = new Register(74, getDoubleEncoding(52), "d52", FPUd);
196    public static final Register d54 = new Register(75, getDoubleEncoding(54), "d54", FPUd);
197    public static final Register d56 = new Register(76, getDoubleEncoding(56), "d56", FPUd);
198    public static final Register d58 = new Register(77, getDoubleEncoding(58), "d58", FPUd);
199    public static final Register d60 = new Register(78, getDoubleEncoding(60), "d60", FPUd);
200    public static final Register d62 = new Register(79, getDoubleEncoding(62), "d62", FPUd);
201
202    // @formatter:off
203    public static final Register[] fpuRegisters = {
204        f0,  f1,  f2,  f3,  f4,  f5,  f6,  f7,
205        f8,  f9,  f10, f11, f12, f13, f14, f15,
206        f16, f17, f18, f19, f20, f21, f22, f23,
207        f24, f25, f26, f27, f28, f29, f30, f31,
208        d32, d34, d36, d38, d40, d42, d44, d46,
209        d48, d50, d52, d54, d56, d58, d60, d62
210    };
211    // @formatter:on
212
213    // @formatter:off
214    public static final Register[] allRegisters = {
215        // CPU
216        r0,  r1,  r2,  r3,  r4,  r5,  r6,  r7,
217        r8,  r9,  r10, r11, r12, r13, r14, r15,
218        r16, r17, r18, r19, r20, r21, r22, r23,
219        r24, r25, r26, r27, r28, r29, r30, r31,
220        // FPU
221        f0,  f1,  f2,  f3,  f4,  f5,  f6,  f7,
222        f8,  f9,  f10, f11, f12, f13, f14, f15,
223        f16, f17, f18, f19, f20, f21, f22, f23,
224        f24, f25, f26, f27, f28, f29, f30, f31,
225        d32, d34, d36, d38, d40, d42, d44, d46,
226        d48, d50, d52, d54, d56, d58, d60, d62
227    };
228    // @formatter:on
229
230    /**
231     * Stack bias for stack and frame pointer loads.
232     */
233    public static final int STACK_BIAS = 0x7ff;
234    /**
235     * In fact there are 64 single floating point registers, 32 of them could be accessed. TODO:
236     * Improve handling of these float registers
237     */
238    public static final int FLOAT_REGISTER_COUNT = 64;
239
240    /**
241     * Alignment for valid memory access.
242     */
243    public static final int MEMORY_ACCESS_ALIGN = 4;
244
245    public static final int INSTRUCTION_SIZE = 4;
246
247    /**
248     * Size to keep free for flushing the register-window to stack.
249     */
250    public static final int REGISTER_SAFE_AREA_SIZE = 128;
251
252    public final Set<CPUFeature> features;
253
254    public SPARC(Set<CPUFeature> features) {
255        super("SPARC", 8, ByteOrder.BIG_ENDIAN, false, allRegisters, LOAD_STORE | STORE_STORE, 1, r31.encoding + FLOAT_REGISTER_COUNT + 1, 8);
256        this.features = features;
257    }
258
259    @Override
260    public boolean canStoreValue(RegisterCategory category, PlatformKind lirKind) {
261        if (!(lirKind instanceof Kind)) {
262            return false;
263        }
264
265        Kind kind = (Kind) lirKind;
266        if (category.equals(CPU)) {
267            switch (kind) {
268                case Boolean:
269                case Byte:
270                case Char:
271                case Short:
272                case Int:
273                case Long:
274                case Object:
275                    return true;
276            }
277        } else if (category.equals(FPUs) && kind.equals(Kind.Float)) {
278            return true;
279        } else if (category.equals(FPUd) && kind.equals(Kind.Double)) {
280            return true;
281        }
282        return false;
283    }
284
285    @Override
286    public PlatformKind getLargestStorableKind(RegisterCategory category) {
287        if (category.equals(CPU)) {
288            return Kind.Long;
289        } else if (category.equals(FPUd)) {
290            return Kind.Double;
291        } else if (category.equals(FPUs)) {
292            return Kind.Float;
293        } else {
294            return Kind.Illegal;
295        }
296    }
297
298    public static int spillSlotSize(TargetDescription td, PlatformKind kind) {
299        return Math.max(td.getSizeInBytes(kind), MEMORY_ACCESS_ALIGN);
300    }
301
302    public static int getDoubleEncoding(int reg) {
303        assert reg < 64 && ((reg & 1) == 0);
304        // ignore v8 assertion for now
305        return (reg & 0x1e) | ((reg & 0x20) >> 5);
306    }
307
308    public static boolean isCPURegister(Register r) {
309        return r.getRegisterCategory().equals(CPU);
310    }
311
312    public static boolean isCPURegister(Register... regs) {
313        for (Register reg : regs) {
314            if (!isCPURegister(reg)) {
315                return false;
316            }
317        }
318        return true;
319    }
320
321    public static boolean isGlobalRegister(Register r) {
322        return isCPURegister(r) && g0.number <= r.number && r.number <= g7.number;
323    }
324
325    public static boolean isSingleFloatRegister(Register r) {
326        return r.name.startsWith("f");
327    }
328
329    public static boolean isDoubleFloatRegister(Register r) {
330        return r.name.startsWith("d");
331    }
332
333    public Set<CPUFeature> getFeatures() {
334        return features;
335    }
336
337    public boolean hasFeature(CPUFeature feature) {
338        return features.contains(feature);
339    }
340
341    public enum CPUFeature {
342        VIS1,
343        VIS2,
344        VIS3,
345        CBCOND
346    }
347}