160 } |
160 } |
161 |
161 |
162 @Override |
162 @Override |
163 public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) { |
163 public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) { |
164 Register dst = asRegister(result); |
164 Register dst = asRegister(result); |
165 masm.loadAddress(dst, (AArch64Address) crb.recordDataReferenceInCode(data), data.getAlignment()); |
165 if (crb.compilationResult.isImmutablePIC()) { |
|
166 crb.recordDataReferenceInCode(data); |
|
167 masm.addressOf(dst); |
|
168 } else { |
|
169 masm.loadAddress(dst, (AArch64Address) crb.recordDataReferenceInCode(data), data.getAlignment()); |
|
170 } |
166 } |
171 } |
167 } |
172 } |
168 |
173 |
169 public static class StackLoadAddressOp extends AArch64LIRInstruction { |
174 public static class StackLoadAddressOp extends AArch64LIRInstruction { |
170 public static final LIRInstructionClass<StackLoadAddressOp> TYPE = LIRInstructionClass.create(StackLoadAddressOp.class); |
175 public static final LIRInstructionClass<StackLoadAddressOp> TYPE = LIRInstructionClass.create(StackLoadAddressOp.class); |
190 } |
195 } |
191 |
196 |
192 public static class MembarOp extends AArch64LIRInstruction { |
197 public static class MembarOp extends AArch64LIRInstruction { |
193 public static final LIRInstructionClass<MembarOp> TYPE = LIRInstructionClass.create(MembarOp.class); |
198 public static final LIRInstructionClass<MembarOp> TYPE = LIRInstructionClass.create(MembarOp.class); |
194 |
199 |
|
200 // For future use. |
195 @SuppressWarnings("unused") private final int barriers; |
201 @SuppressWarnings("unused") private final int barriers; |
196 |
202 |
197 public MembarOp(int barriers) { |
203 public MembarOp(int barriers) { |
198 super(TYPE); |
204 super(TYPE); |
199 this.barriers = barriers; |
205 this.barriers = barriers; |
200 } |
206 } |
201 |
207 |
202 @Override |
208 @Override |
203 public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) { |
209 // The odd-looking @SuppressWarnings("all") is here because of |
|
210 // a compiler bug which warns that crb is unused, and also |
|
211 // warns that @SuppressWarnings("unused") is unnecessary. |
|
212 public void emitCode(@SuppressWarnings("all") CompilationResultBuilder crb, AArch64MacroAssembler masm) { |
204 // As I understand it load acquire/store release have the same semantics as on IA64 |
213 // As I understand it load acquire/store release have the same semantics as on IA64 |
205 // and allow us to handle LoadStore, LoadLoad and StoreStore without an explicit |
214 // and allow us to handle LoadStore, LoadLoad and StoreStore without an explicit |
206 // barrier. |
215 // barrier. |
207 // But Graal support to figure out if a load/store is volatile is non-existant so for |
216 // But Graal support to figure out if a load/store is volatile is non-existant so for |
208 // now |
217 // now just use memory barriers everywhere. |
209 // just use |
|
210 // memory barriers everywhere. |
|
211 // if ((barrier & MemoryBarriers.STORE_LOAD) != 0) { |
218 // if ((barrier & MemoryBarriers.STORE_LOAD) != 0) { |
212 masm.dmb(AArch64MacroAssembler.BarrierKind.ANY_ANY); |
219 masm.dmb(AArch64MacroAssembler.BarrierKind.ANY_ANY); |
213 // } |
220 // } |
214 } |
221 } |
215 } |
222 } |
406 } else { |
413 } else { |
407 masm.fmov(size, dst, src); |
414 masm.fmov(size, dst, src); |
408 } |
415 } |
409 } |
416 } |
410 |
417 |
411 private static void reg2stack(CompilationResultBuilder crb, AArch64MacroAssembler masm, AllocatableValue result, AllocatableValue input) { |
418 static void reg2stack(CompilationResultBuilder crb, AArch64MacroAssembler masm, AllocatableValue result, AllocatableValue input) { |
412 AArch64Address dest = loadStackSlotAddress(crb, masm, asStackSlot(result), Value.ILLEGAL); |
419 AArch64Address dest = loadStackSlotAddress(crb, masm, asStackSlot(result), Value.ILLEGAL); |
413 Register src = asRegister(input); |
420 Register src = asRegister(input); |
414 // use the slot kind to define the operand size |
421 // use the slot kind to define the operand size |
415 AArch64Kind kind = (AArch64Kind) result.getPlatformKind(); |
422 AArch64Kind kind = (AArch64Kind) result.getPlatformKind(); |
416 final int size = kind.getSizeInBytes() * Byte.SIZE; |
423 final int size = kind.getSizeInBytes() * Byte.SIZE; |
419 } else { |
426 } else { |
420 masm.fstr(size, src, dest); |
427 masm.fstr(size, src, dest); |
421 } |
428 } |
422 } |
429 } |
423 |
430 |
424 private static void stack2reg(CompilationResultBuilder crb, AArch64MacroAssembler masm, AllocatableValue result, AllocatableValue input) { |
431 static void stack2reg(CompilationResultBuilder crb, AArch64MacroAssembler masm, AllocatableValue result, AllocatableValue input) { |
425 AArch64Kind kind = (AArch64Kind) input.getPlatformKind(); |
432 AArch64Kind kind = (AArch64Kind) input.getPlatformKind(); |
426 // use the slot kind to define the operand size |
433 // use the slot kind to define the operand size |
427 final int size = kind.getSizeInBytes() * Byte.SIZE; |
434 final int size = kind.getSizeInBytes() * Byte.SIZE; |
428 if (kind.isInteger()) { |
435 if (kind.isInteger()) { |
429 AArch64Address src = loadStackSlotAddress(crb, masm, asStackSlot(input), result); |
436 AArch64Address src = loadStackSlotAddress(crb, masm, asStackSlot(input), result); |
464 masm.mov(dst, input.asLong()); |
471 masm.mov(dst, input.asLong()); |
465 break; |
472 break; |
466 case Float: |
473 case Float: |
467 if (AArch64MacroAssembler.isFloatImmediate(input.asFloat())) { |
474 if (AArch64MacroAssembler.isFloatImmediate(input.asFloat())) { |
468 masm.fmov(32, dst, input.asFloat()); |
475 masm.fmov(32, dst, input.asFloat()); |
|
476 } else if (crb.compilationResult.isImmutablePIC()) { |
|
477 try (ScratchRegister scr = masm.getScratchRegister()) { |
|
478 Register scratch = scr.getRegister(); |
|
479 masm.mov(scratch, Float.floatToRawIntBits(input.asFloat())); |
|
480 masm.fmov(32, dst, scratch); |
|
481 } |
469 } else { |
482 } else { |
470 masm.fldr(32, dst, (AArch64Address) crb.asFloatConstRef(input)); |
483 masm.fldr(32, dst, (AArch64Address) crb.asFloatConstRef(input)); |
471 } |
484 } |
472 break; |
485 break; |
473 case Double: |
486 case Double: |
474 if (AArch64MacroAssembler.isDoubleImmediate(input.asDouble())) { |
487 if (AArch64MacroAssembler.isDoubleImmediate(input.asDouble())) { |
475 masm.fmov(64, dst, input.asDouble()); |
488 masm.fmov(64, dst, input.asDouble()); |
|
489 } else if (crb.compilationResult.isImmutablePIC()) { |
|
490 try (ScratchRegister scr = masm.getScratchRegister()) { |
|
491 Register scratch = scr.getRegister(); |
|
492 masm.mov(scratch, Double.doubleToRawLongBits(input.asDouble())); |
|
493 masm.fmov(64, dst, scratch); |
|
494 } |
476 } else { |
495 } else { |
477 masm.fldr(64, dst, (AArch64Address) crb.asDoubleConstRef(input)); |
496 masm.fldr(64, dst, (AArch64Address) crb.asDoubleConstRef(input)); |
478 } |
497 } |
479 break; |
498 break; |
480 case Object: |
499 case Object: |