Mercurial > hg > truffle
annotate graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java @ 19526:8fc336a04d77
Create TYPE fields for LIRInstruction and CompositeValue. Renaming NodeClass#get to NodeClass#create.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Fri, 20 Feb 2015 22:22:55 +0100 |
parents | 1c92d437179b |
children | 96ab2078eeaf |
rev | line source |
---|---|
15345 | 1 /* |
19526
8fc336a04d77
Create TYPE fields for LIRInstruction and CompositeValue. Renaming NodeClass#get to NodeClass#create.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
18443
diff
changeset
|
2 * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. |
15345 | 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. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 package com.oracle.graal.lir.sparc; | |
24 | |
18425
b856446ff7e0
Introduce StackSlotValue and VirtualStackSlot.
Josef Eisl <josef.eisl@jku.at>
parents:
18163
diff
changeset
|
25 import static com.oracle.graal.api.code.ValueUtil.*; |
15345 | 26 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; |
27 | |
28 import java.util.*; | |
29 | |
30 import com.oracle.graal.api.code.*; | |
31 import com.oracle.graal.asm.sparc.*; | |
18425
b856446ff7e0
Introduce StackSlotValue and VirtualStackSlot.
Josef Eisl <josef.eisl@jku.at>
parents:
18163
diff
changeset
|
32 import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf; |
b856446ff7e0
Introduce StackSlotValue and VirtualStackSlot.
Josef Eisl <josef.eisl@jku.at>
parents:
18163
diff
changeset
|
33 import com.oracle.graal.asm.sparc.SPARCAssembler.Stx; |
15345 | 34 import com.oracle.graal.lir.*; |
35 import com.oracle.graal.lir.StandardOp.SaveRegistersOp; | |
36 import com.oracle.graal.lir.asm.*; | |
18443
1c92d437179b
FrameMapBuilder: move into package.
Josef Eisl <josef.eisl@jku.at>
parents:
18425
diff
changeset
|
37 import com.oracle.graal.lir.framemap.*; |
16932
4d77f938aa02
[SPARC] Exclude AMD64 tests from SPARC testrun, always use tmp register when using StrategySwitch, using registerSaver in EnterUnpackStackFrame, LeaveCurrentStackframe, adding guarantee to load offsets when doing load reg+imm13 when the imm value does not fit in 13 bit, assertions for scratch register usage (tmp/def)
Stefan Anzinger <stefan.anzinger@gmail.com>
parents:
16094
diff
changeset
|
38 import com.oracle.graal.sparc.*; |
15345 | 39 |
40 /** | |
41 * Saves registers to stack slots. | |
42 */ | |
43 @Opcode("SAVE_REGISTER") | |
44 public class SPARCSaveRegistersOp extends SPARCLIRInstruction implements SaveRegistersOp { | |
19526
8fc336a04d77
Create TYPE fields for LIRInstruction and CompositeValue. Renaming NodeClass#get to NodeClass#create.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
18443
diff
changeset
|
45 public static final LIRInstructionClass<SPARCSaveRegistersOp> TYPE = LIRInstructionClass.create(SPARCSaveRegistersOp.class); |
18163
c88ab4f1f04a
re-enabled Checkstyle with the release of 6.0 that supports Java 8; fixed existing Checkstyle warnings
Doug Simon <doug.simon@oracle.com>
parents:
18140
diff
changeset
|
46 public static final Register RETURN_REGISTER_STORAGE = SPARC.d62; |
15345 | 47 /** |
48 * The registers (potentially) saved by this operation. | |
49 */ | |
50 protected final Register[] savedRegisters; | |
51 | |
52 /** | |
53 * The slots to which the registers are saved. | |
54 */ | |
18425
b856446ff7e0
Introduce StackSlotValue and VirtualStackSlot.
Josef Eisl <josef.eisl@jku.at>
parents:
18163
diff
changeset
|
55 @Def(STACK) protected final StackSlotValue[] slots; |
15345 | 56 |
57 /** | |
58 * Specifies if {@link #remove(Set)} should have an effect. | |
59 */ | |
60 protected final boolean supportsRemove; | |
61 | |
62 /** | |
63 * | |
64 * @param savedRegisters the registers saved by this operation which may be subject to | |
65 * {@linkplain #remove(Set) pruning} | |
18425
b856446ff7e0
Introduce StackSlotValue and VirtualStackSlot.
Josef Eisl <josef.eisl@jku.at>
parents:
18163
diff
changeset
|
66 * @param savedRegisterLocations the slots to which the registers are saved |
15345 | 67 * @param supportsRemove determines if registers can be {@linkplain #remove(Set) pruned} |
68 */ | |
18425
b856446ff7e0
Introduce StackSlotValue and VirtualStackSlot.
Josef Eisl <josef.eisl@jku.at>
parents:
18163
diff
changeset
|
69 public SPARCSaveRegistersOp(Register[] savedRegisters, StackSlotValue[] savedRegisterLocations, boolean supportsRemove) { |
19526
8fc336a04d77
Create TYPE fields for LIRInstruction and CompositeValue. Renaming NodeClass#get to NodeClass#create.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
18443
diff
changeset
|
70 super(TYPE); |
18425
b856446ff7e0
Introduce StackSlotValue and VirtualStackSlot.
Josef Eisl <josef.eisl@jku.at>
parents:
18163
diff
changeset
|
71 assert Arrays.asList(savedRegisterLocations).stream().allMatch(ValueUtil::isVirtualStackSlot); |
15345 | 72 this.savedRegisters = savedRegisters; |
18425
b856446ff7e0
Introduce StackSlotValue and VirtualStackSlot.
Josef Eisl <josef.eisl@jku.at>
parents:
18163
diff
changeset
|
73 this.slots = savedRegisterLocations; |
15345 | 74 this.supportsRemove = supportsRemove; |
75 } | |
76 | |
77 private static void saveRegister(CompilationResultBuilder crb, SPARCMacroAssembler masm, StackSlot result, Register register) { | |
16094
c0b8d395368b
Introduce LIRKind to accurately track oop references in backend.
Roland Schatz <roland.schatz@oracle.com>
parents:
15345
diff
changeset
|
78 RegisterValue input = register.asValue(result.getLIRKind()); |
17206
2d401b9ca70d
[SPARC] Improve the lookup for delayable candidates, renaming interfaces/methods
Stefan Anzinger <stefan.anzinger@oracle.com>
parents:
17177
diff
changeset
|
79 SPARCMove.move(crb, masm, result, input, SPARCDelayedControlTransfer.DUMMY); |
15345 | 80 } |
81 | |
82 @Override | |
83 public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { | |
17082
f8586d059f9d
[SPARC] make compatible for CPU without VIS3 and do some cleanup
Stefan Anzinger <stefan.anzinger@oracle.com>
parents:
17026
diff
changeset
|
84 // Can be used with VIS3 |
f8586d059f9d
[SPARC] make compatible for CPU without VIS3 and do some cleanup
Stefan Anzinger <stefan.anzinger@oracle.com>
parents:
17026
diff
changeset
|
85 // new Movxtod(SPARC.i0, RETURN_REGISTER_STORAGE).emit(masm); |
f8586d059f9d
[SPARC] make compatible for CPU without VIS3 and do some cleanup
Stefan Anzinger <stefan.anzinger@oracle.com>
parents:
17026
diff
changeset
|
86 // We abuse the first stackslot for transferring i0 to return_register_storage |
f8586d059f9d
[SPARC] make compatible for CPU without VIS3 and do some cleanup
Stefan Anzinger <stefan.anzinger@oracle.com>
parents:
17026
diff
changeset
|
87 // assert slots.length >= 1; |
f8586d059f9d
[SPARC] make compatible for CPU without VIS3 and do some cleanup
Stefan Anzinger <stefan.anzinger@oracle.com>
parents:
17026
diff
changeset
|
88 SPARCAddress slot0Address = (SPARCAddress) crb.asAddress(slots[0]); |
f8586d059f9d
[SPARC] make compatible for CPU without VIS3 and do some cleanup
Stefan Anzinger <stefan.anzinger@oracle.com>
parents:
17026
diff
changeset
|
89 new Stx(SPARC.i0, slot0Address).emit(masm); |
f8586d059f9d
[SPARC] make compatible for CPU without VIS3 and do some cleanup
Stefan Anzinger <stefan.anzinger@oracle.com>
parents:
17026
diff
changeset
|
90 new Lddf(slot0Address, RETURN_REGISTER_STORAGE).emit(masm); |
f8586d059f9d
[SPARC] make compatible for CPU without VIS3 and do some cleanup
Stefan Anzinger <stefan.anzinger@oracle.com>
parents:
17026
diff
changeset
|
91 |
f8586d059f9d
[SPARC] make compatible for CPU without VIS3 and do some cleanup
Stefan Anzinger <stefan.anzinger@oracle.com>
parents:
17026
diff
changeset
|
92 // Now save the registers |
15345 | 93 for (int i = 0; i < savedRegisters.length; i++) { |
94 if (savedRegisters[i] != null) { | |
18425
b856446ff7e0
Introduce StackSlotValue and VirtualStackSlot.
Josef Eisl <josef.eisl@jku.at>
parents:
18163
diff
changeset
|
95 assert isStackSlot(slots[i]) : "not a StackSlot: " + slots[i]; |
b856446ff7e0
Introduce StackSlotValue and VirtualStackSlot.
Josef Eisl <josef.eisl@jku.at>
parents:
18163
diff
changeset
|
96 saveRegister(crb, masm, asStackSlot(slots[i]), savedRegisters[i]); |
15345 | 97 } |
98 } | |
99 } | |
100 | |
18425
b856446ff7e0
Introduce StackSlotValue and VirtualStackSlot.
Josef Eisl <josef.eisl@jku.at>
parents:
18163
diff
changeset
|
101 public StackSlotValue[] getSlots() { |
15345 | 102 return slots; |
103 } | |
104 | |
105 public boolean supportsRemove() { | |
106 return supportsRemove; | |
107 } | |
108 | |
109 public int remove(Set<Register> doNotSave) { | |
110 if (!supportsRemove) { | |
111 throw new UnsupportedOperationException(); | |
112 } | |
113 return prune(doNotSave, savedRegisters); | |
114 } | |
115 | |
116 static int prune(Set<Register> toRemove, Register[] registers) { | |
117 int pruned = 0; | |
118 for (int i = 0; i < registers.length; i++) { | |
119 if (registers[i] != null) { | |
120 if (toRemove.contains(registers[i])) { | |
121 registers[i] = null; | |
122 pruned++; | |
123 } | |
124 } | |
125 } | |
126 return pruned; | |
127 } | |
128 | |
129 public RegisterSaveLayout getMap(FrameMap frameMap) { | |
130 int total = 0; | |
131 for (int i = 0; i < savedRegisters.length; i++) { | |
132 if (savedRegisters[i] != null) { | |
133 total++; | |
134 } | |
135 } | |
136 Register[] keys = new Register[total]; | |
137 int[] values = new int[total]; | |
138 if (total != 0) { | |
139 int mapIndex = 0; | |
140 for (int i = 0; i < savedRegisters.length; i++) { | |
141 if (savedRegisters[i] != null) { | |
142 keys[mapIndex] = savedRegisters[i]; | |
18425
b856446ff7e0
Introduce StackSlotValue and VirtualStackSlot.
Josef Eisl <josef.eisl@jku.at>
parents:
18163
diff
changeset
|
143 assert isStackSlot(slots[i]) : "not a StackSlot: " + slots[i]; |
b856446ff7e0
Introduce StackSlotValue and VirtualStackSlot.
Josef Eisl <josef.eisl@jku.at>
parents:
18163
diff
changeset
|
144 StackSlot slot = asStackSlot(slots[i]); |
18140
185bd9096c88
Remove FrameMap.indexForStackSlot().
Josef Eisl <josef.eisl@jku.at>
parents:
17206
diff
changeset
|
145 values[mapIndex] = indexForStackSlot(frameMap, slot); |
15345 | 146 mapIndex++; |
147 } | |
148 } | |
149 assert mapIndex == total; | |
150 } | |
151 return new RegisterSaveLayout(keys, values); | |
152 } | |
18140
185bd9096c88
Remove FrameMap.indexForStackSlot().
Josef Eisl <josef.eisl@jku.at>
parents:
17206
diff
changeset
|
153 |
185bd9096c88
Remove FrameMap.indexForStackSlot().
Josef Eisl <josef.eisl@jku.at>
parents:
17206
diff
changeset
|
154 /** |
185bd9096c88
Remove FrameMap.indexForStackSlot().
Josef Eisl <josef.eisl@jku.at>
parents:
17206
diff
changeset
|
155 * Computes the index of a stack slot relative to slot 0. This is also the bit index of stack |
185bd9096c88
Remove FrameMap.indexForStackSlot().
Josef Eisl <josef.eisl@jku.at>
parents:
17206
diff
changeset
|
156 * slots in the reference map. |
185bd9096c88
Remove FrameMap.indexForStackSlot().
Josef Eisl <josef.eisl@jku.at>
parents:
17206
diff
changeset
|
157 * |
185bd9096c88
Remove FrameMap.indexForStackSlot().
Josef Eisl <josef.eisl@jku.at>
parents:
17206
diff
changeset
|
158 * @param slot a stack slot |
185bd9096c88
Remove FrameMap.indexForStackSlot().
Josef Eisl <josef.eisl@jku.at>
parents:
17206
diff
changeset
|
159 * @return the index of the stack slot |
185bd9096c88
Remove FrameMap.indexForStackSlot().
Josef Eisl <josef.eisl@jku.at>
parents:
17206
diff
changeset
|
160 */ |
185bd9096c88
Remove FrameMap.indexForStackSlot().
Josef Eisl <josef.eisl@jku.at>
parents:
17206
diff
changeset
|
161 private static int indexForStackSlot(FrameMap frameMap, StackSlot slot) { |
185bd9096c88
Remove FrameMap.indexForStackSlot().
Josef Eisl <josef.eisl@jku.at>
parents:
17206
diff
changeset
|
162 assert frameMap.offsetForStackSlot(slot) % frameMap.getTarget().wordSize == 0; |
185bd9096c88
Remove FrameMap.indexForStackSlot().
Josef Eisl <josef.eisl@jku.at>
parents:
17206
diff
changeset
|
163 int value = frameMap.offsetForStackSlot(slot) / frameMap.getTarget().wordSize; |
185bd9096c88
Remove FrameMap.indexForStackSlot().
Josef Eisl <josef.eisl@jku.at>
parents:
17206
diff
changeset
|
164 return value; |
185bd9096c88
Remove FrameMap.indexForStackSlot().
Josef Eisl <josef.eisl@jku.at>
parents:
17206
diff
changeset
|
165 } |
15345 | 166 } |