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 org.graalvm.compiler.hotspot.amd64;
24
25 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
26 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
27 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
28 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
29 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
30 import static jdk.vm.ci.code.ValueUtil.asRegister;
31 import static jdk.vm.ci.code.ValueUtil.isRegister;
32 import static jdk.vm.ci.code.ValueUtil.isStackSlot;
33
34 import org.graalvm.compiler.asm.Label;
35 import org.graalvm.compiler.asm.amd64.AMD64Address;
36 import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
37 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
38 import org.graalvm.compiler.debug.GraalError;
39 import org.graalvm.compiler.hotspot.CompressEncoding;
40 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
41 import org.graalvm.compiler.lir.LIRInstructionClass;
42 import org.graalvm.compiler.lir.StandardOp.LoadConstantOp;
43 import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
44 import org.graalvm.compiler.lir.amd64.AMD64Move;
45 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
46
47 import jdk.vm.ci.amd64.AMD64Kind;
48 import jdk.vm.ci.code.Register;
49 import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
50 import jdk.vm.ci.hotspot.HotSpotObjectConstant;
51 import jdk.vm.ci.meta.AllocatableValue;
52 import jdk.vm.ci.meta.Constant;
53
54 public class AMD64HotSpotMove {
55
56 public static final class HotSpotLoadObjectConstantOp extends AMD64LIRInstruction implements LoadConstantOp {
57 public static final LIRInstructionClass<HotSpotLoadObjectConstantOp> TYPE = LIRInstructionClass.create(HotSpotLoadObjectConstantOp.class);
58
59 @Def({REG, STACK}) private AllocatableValue result;
60 private final HotSpotObjectConstant input;
61
62 public HotSpotLoadObjectConstantOp(AllocatableValue result, HotSpotObjectConstant input) {
63 super(TYPE);
64 this.result = result;
65 this.input = input;
66 }
67
68 @Override
69 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
70 if (GeneratePIC.getValue()) {
71 throw GraalError.shouldNotReachHere("Object constant load should not be happening directly");
72 }
73 boolean compressed = input.isCompressed();
74 if (crb.target.inlineObjects) {
75 crb.recordInlineDataInCode(input);
76 if (isRegister(result)) {
77 if (compressed) {
78 masm.movl(asRegister(result), 0xDEADDEAD);
79 } else {
80 masm.movq(asRegister(result), 0xDEADDEADDEADDEADL);
81 }
82 } else {
83 assert isStackSlot(result);
84 if (compressed) {
85 masm.movl((AMD64Address) crb.asAddress(result), 0xDEADDEAD);
86 } else {
87 throw GraalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
88 }
89 }
90 } else {
129 masm.movq(asRegister(result), masm.getPlaceholder(-1));
130 crb.recordMark(config.MARKID_NARROW_KLASS_BASE_ADDRESS);
131 }
132
133 }
134
135 public static final class HotSpotLoadMetaspaceConstantOp extends AMD64LIRInstruction implements LoadConstantOp {
136 public static final LIRInstructionClass<HotSpotLoadMetaspaceConstantOp> TYPE = LIRInstructionClass.create(HotSpotLoadMetaspaceConstantOp.class);
137
138 @Def({REG, STACK}) private AllocatableValue result;
139 private final HotSpotMetaspaceConstant input;
140
141 public HotSpotLoadMetaspaceConstantOp(AllocatableValue result, HotSpotMetaspaceConstant input) {
142 super(TYPE);
143 this.result = result;
144 this.input = input;
145 }
146
147 @Override
148 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
149 if (GeneratePIC.getValue()) {
150 throw GraalError.shouldNotReachHere("Metaspace constant load should not be happening directly");
151 }
152 boolean compressed = input.isCompressed();
153 if (isRegister(result)) {
154 if (compressed) {
155 crb.recordInlineDataInCode(input);
156 masm.movl(asRegister(result), 0xDEADDEAD);
157 } else {
158 crb.recordInlineDataInCode(input);
159 masm.movq(asRegister(result), 0xDEADDEADDEADDEADL);
160 }
161 } else {
162 assert isStackSlot(result);
163 if (compressed) {
164 crb.recordInlineDataInCode(input);
165 masm.movl((AMD64Address) crb.asAddress(result), 0xDEADDEAD);
166 } else {
167 throw GraalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
168 }
169 }
187 private final boolean nonNull;
188
189 @Def({REG, HINT}) protected AllocatableValue result;
190 @Use({REG}) protected AllocatableValue input;
191 @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister;
192
193 public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) {
194 super(TYPE);
195 this.result = result;
196 this.input = input;
197 this.baseRegister = baseRegister;
198 this.encoding = encoding;
199 this.nonNull = nonNull;
200 }
201
202 @Override
203 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
204 AMD64Move.move(AMD64Kind.QWORD, crb, masm, result, input);
205
206 Register resReg = asRegister(result);
207 if (encoding.base != 0 || GeneratePIC.getValue()) {
208 Register baseReg = asRegister(baseRegister);
209 if (!nonNull) {
210 masm.testq(resReg, resReg);
211 masm.cmovq(ConditionFlag.Equal, resReg, baseReg);
212 }
213 masm.subq(resReg, baseReg);
214 }
215
216 if (encoding.shift != 0) {
217 masm.shrq(resReg, encoding.shift);
218 }
219 }
220 }
221
222 public static final class UncompressPointer extends AMD64LIRInstruction {
223 public static final LIRInstructionClass<UncompressPointer> TYPE = LIRInstructionClass.create(UncompressPointer.class);
224
225 private final CompressEncoding encoding;
226 private final boolean nonNull;
227
228 @Def({REG, HINT}) protected AllocatableValue result;
229 @Use({REG}) protected AllocatableValue input;
230 @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister;
231
232 public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) {
233 super(TYPE);
234 this.result = result;
235 this.input = input;
236 this.baseRegister = baseRegister;
237 this.encoding = encoding;
238 this.nonNull = nonNull;
239 }
240
241 @Override
242 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
243 AMD64Move.move(AMD64Kind.DWORD, crb, masm, result, input);
244
245 Register resReg = asRegister(result);
246 if (encoding.shift != 0) {
247 masm.shlq(resReg, encoding.shift);
248 }
249
250 if (encoding.base != 0 || GeneratePIC.getValue()) {
251 if (nonNull) {
252 masm.addq(resReg, asRegister(baseRegister));
253 } else {
254 if (encoding.shift == 0) {
255 // if encoding.shift != 0, the flags are already set by the shlq
256 masm.testq(resReg, resReg);
257 }
258
259 Label done = new Label();
260 masm.jccb(ConditionFlag.Equal, done);
261 masm.addq(resReg, asRegister(baseRegister));
262 masm.bind(done);
263 }
264 }
265 }
266 }
267
268 public static void decodeKlassPointer(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register register, Register scratch, AMD64Address address, GraalHotSpotVMConfig config) {
269 CompressEncoding encoding = config.getKlassEncoding();
270 masm.movl(register, address);
271 if (encoding.shift != 0) {
272 assert encoding.alignment == encoding.shift : "Decode algorithm is wrong";
273 masm.shlq(register, encoding.alignment);
274 }
275 if (GeneratePIC.getValue() || encoding.base != 0) {
276 if (GeneratePIC.getValue()) {
277 masm.movq(scratch, masm.getPlaceholder(-1));
278 crb.recordMark(config.MARKID_NARROW_KLASS_BASE_ADDRESS);
279 } else {
280 assert encoding.base != 0;
281 masm.movq(scratch, encoding.base);
282 }
283 masm.addq(register, scratch);
284 }
285 }
286 }
|
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 org.graalvm.compiler.hotspot.amd64;
24
25 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
26 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
27 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
28 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
29 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
30 import static jdk.vm.ci.code.ValueUtil.asRegister;
31 import static jdk.vm.ci.code.ValueUtil.isRegister;
32 import static jdk.vm.ci.code.ValueUtil.isStackSlot;
33
34 import org.graalvm.compiler.asm.Label;
35 import org.graalvm.compiler.asm.amd64.AMD64Address;
36 import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
37 import org.graalvm.compiler.core.common.CompressEncoding;
38 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
39 import org.graalvm.compiler.debug.GraalError;
40 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
41 import org.graalvm.compiler.lir.LIRInstructionClass;
42 import org.graalvm.compiler.lir.StandardOp.LoadConstantOp;
43 import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
44 import org.graalvm.compiler.lir.amd64.AMD64Move;
45 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
46
47 import jdk.vm.ci.amd64.AMD64Kind;
48 import jdk.vm.ci.code.Register;
49 import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
50 import jdk.vm.ci.hotspot.HotSpotObjectConstant;
51 import jdk.vm.ci.meta.AllocatableValue;
52 import jdk.vm.ci.meta.Constant;
53
54 public class AMD64HotSpotMove {
55
56 public static final class HotSpotLoadObjectConstantOp extends AMD64LIRInstruction implements LoadConstantOp {
57 public static final LIRInstructionClass<HotSpotLoadObjectConstantOp> TYPE = LIRInstructionClass.create(HotSpotLoadObjectConstantOp.class);
58
59 @Def({REG, STACK}) private AllocatableValue result;
60 private final HotSpotObjectConstant input;
61
62 public HotSpotLoadObjectConstantOp(AllocatableValue result, HotSpotObjectConstant input) {
63 super(TYPE);
64 this.result = result;
65 this.input = input;
66 }
67
68 @Override
69 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
70 if (GeneratePIC.getValue(crb.getOptions())) {
71 throw GraalError.shouldNotReachHere("Object constant load should not be happening directly");
72 }
73 boolean compressed = input.isCompressed();
74 if (crb.target.inlineObjects) {
75 crb.recordInlineDataInCode(input);
76 if (isRegister(result)) {
77 if (compressed) {
78 masm.movl(asRegister(result), 0xDEADDEAD);
79 } else {
80 masm.movq(asRegister(result), 0xDEADDEADDEADDEADL);
81 }
82 } else {
83 assert isStackSlot(result);
84 if (compressed) {
85 masm.movl((AMD64Address) crb.asAddress(result), 0xDEADDEAD);
86 } else {
87 throw GraalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
88 }
89 }
90 } else {
129 masm.movq(asRegister(result), masm.getPlaceholder(-1));
130 crb.recordMark(config.MARKID_NARROW_KLASS_BASE_ADDRESS);
131 }
132
133 }
134
135 public static final class HotSpotLoadMetaspaceConstantOp extends AMD64LIRInstruction implements LoadConstantOp {
136 public static final LIRInstructionClass<HotSpotLoadMetaspaceConstantOp> TYPE = LIRInstructionClass.create(HotSpotLoadMetaspaceConstantOp.class);
137
138 @Def({REG, STACK}) private AllocatableValue result;
139 private final HotSpotMetaspaceConstant input;
140
141 public HotSpotLoadMetaspaceConstantOp(AllocatableValue result, HotSpotMetaspaceConstant input) {
142 super(TYPE);
143 this.result = result;
144 this.input = input;
145 }
146
147 @Override
148 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
149 if (GeneratePIC.getValue(crb.getOptions())) {
150 throw GraalError.shouldNotReachHere("Metaspace constant load should not be happening directly");
151 }
152 boolean compressed = input.isCompressed();
153 if (isRegister(result)) {
154 if (compressed) {
155 crb.recordInlineDataInCode(input);
156 masm.movl(asRegister(result), 0xDEADDEAD);
157 } else {
158 crb.recordInlineDataInCode(input);
159 masm.movq(asRegister(result), 0xDEADDEADDEADDEADL);
160 }
161 } else {
162 assert isStackSlot(result);
163 if (compressed) {
164 crb.recordInlineDataInCode(input);
165 masm.movl((AMD64Address) crb.asAddress(result), 0xDEADDEAD);
166 } else {
167 throw GraalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
168 }
169 }
187 private final boolean nonNull;
188
189 @Def({REG, HINT}) protected AllocatableValue result;
190 @Use({REG}) protected AllocatableValue input;
191 @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister;
192
193 public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) {
194 super(TYPE);
195 this.result = result;
196 this.input = input;
197 this.baseRegister = baseRegister;
198 this.encoding = encoding;
199 this.nonNull = nonNull;
200 }
201
202 @Override
203 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
204 AMD64Move.move(AMD64Kind.QWORD, crb, masm, result, input);
205
206 Register resReg = asRegister(result);
207 if (encoding.hasBase() || GeneratePIC.getValue(crb.getOptions())) {
208 Register baseReg = asRegister(baseRegister);
209 if (!nonNull) {
210 masm.testq(resReg, resReg);
211 masm.cmovq(ConditionFlag.Equal, resReg, baseReg);
212 }
213 masm.subq(resReg, baseReg);
214 }
215
216 if (encoding.hasShift()) {
217 masm.shrq(resReg, encoding.getShift());
218 }
219 }
220 }
221
222 public static final class UncompressPointer extends AMD64LIRInstruction {
223 public static final LIRInstructionClass<UncompressPointer> TYPE = LIRInstructionClass.create(UncompressPointer.class);
224
225 private final CompressEncoding encoding;
226 private final boolean nonNull;
227
228 @Def({REG, HINT}) protected AllocatableValue result;
229 @Use({REG}) protected AllocatableValue input;
230 @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister;
231
232 public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) {
233 super(TYPE);
234 this.result = result;
235 this.input = input;
236 this.baseRegister = baseRegister;
237 this.encoding = encoding;
238 this.nonNull = nonNull;
239 }
240
241 @Override
242 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
243 AMD64Move.move(AMD64Kind.DWORD, crb, masm, result, input);
244
245 Register resReg = asRegister(result);
246 if (encoding.getShift() != 0) {
247 masm.shlq(resReg, encoding.getShift());
248 }
249
250 if (encoding.hasBase() || GeneratePIC.getValue(crb.getOptions())) {
251 if (nonNull) {
252 masm.addq(resReg, asRegister(baseRegister));
253 } else {
254 if (!encoding.hasShift()) {
255 // if encoding.shift != 0, the flags are already set by the shlq
256 masm.testq(resReg, resReg);
257 }
258
259 Label done = new Label();
260 masm.jccb(ConditionFlag.Equal, done);
261 masm.addq(resReg, asRegister(baseRegister));
262 masm.bind(done);
263 }
264 }
265 }
266 }
267
268 public static void decodeKlassPointer(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register register, Register scratch, AMD64Address address, GraalHotSpotVMConfig config) {
269 CompressEncoding encoding = config.getKlassEncoding();
270 masm.movl(register, address);
271 if (encoding.getShift() != 0) {
272 masm.shlq(register, encoding.getShift());
273 }
274 boolean pic = GeneratePIC.getValue(crb.getOptions());
275 if (pic || encoding.hasBase()) {
276 if (pic) {
277 masm.movq(scratch, masm.getPlaceholder(-1));
278 crb.recordMark(config.MARKID_NARROW_KLASS_BASE_ADDRESS);
279 } else {
280 assert encoding.getBase() != 0;
281 masm.movq(scratch, encoding.getBase());
282 }
283 masm.addq(register, scratch);
284 }
285 }
286 }
|