154 } |
154 } |
155 |
155 |
156 @Override |
156 @Override |
157 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { |
157 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { |
158 if (isRegister(result)) { |
158 if (isRegister(result)) { |
159 const2reg(crb, masm, asRegister(result), input); |
159 const2reg(crb, masm, asRegister(result), input, (AMD64Kind) result.getPlatformKind()); |
160 } else { |
160 } else { |
161 assert isStackSlot(result); |
161 assert isStackSlot(result); |
162 const2stack(crb, masm, result, input); |
162 const2stack(crb, masm, result, input); |
163 } |
163 } |
164 } |
164 } |
555 } else { |
555 } else { |
556 throw GraalError.shouldNotReachHere(); |
556 throw GraalError.shouldNotReachHere(); |
557 } |
557 } |
558 } else if (isJavaConstant(input)) { |
558 } else if (isJavaConstant(input)) { |
559 if (isRegister(result)) { |
559 if (isRegister(result)) { |
560 const2reg(crb, masm, asRegister(result), asJavaConstant(input)); |
560 const2reg(crb, masm, asRegister(result), asJavaConstant(input), moveKind); |
561 } else if (isStackSlot(result)) { |
561 } else if (isStackSlot(result)) { |
562 const2stack(crb, masm, result, asJavaConstant(input)); |
562 const2stack(crb, masm, result, asJavaConstant(input)); |
563 } else { |
563 } else { |
564 throw GraalError.shouldNotReachHere(); |
564 throw GraalError.shouldNotReachHere(); |
565 } |
565 } |
643 default: |
643 default: |
644 throw GraalError.shouldNotReachHere(); |
644 throw GraalError.shouldNotReachHere(); |
645 } |
645 } |
646 } |
646 } |
647 |
647 |
648 public static void const2reg(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register result, JavaConstant input) { |
648 public static void const2reg(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register result, JavaConstant input, AMD64Kind moveKind) { |
649 /* |
649 /* |
650 * Note: we use the kind of the input operand (and not the kind of the result operand) |
650 * Note: we use the kind of the input operand (and not the kind of the result operand) |
651 * because they don't match in all cases. For example, an object constant can be loaded to a |
651 * because they don't match in all cases. For example, an object constant can be loaded to a |
652 * long register when unsafe casts occurred (e.g., for a write barrier where arithmetic |
652 * long register when unsafe casts occurred (e.g., for a write barrier where arithmetic |
653 * operations are then performed on the pointer). |
653 * operations are then performed on the pointer). |
689 } else { |
689 } else { |
690 masm.movdbl(result, (AMD64Address) crb.asDoubleConstRef(input)); |
690 masm.movdbl(result, (AMD64Address) crb.asDoubleConstRef(input)); |
691 } |
691 } |
692 break; |
692 break; |
693 case Object: |
693 case Object: |
|
694 assert moveKind != null : "a nun-null moveKind is required for loading an object constant"; |
694 // Do not optimize with an XOR as this instruction may be between |
695 // Do not optimize with an XOR as this instruction may be between |
695 // a CMP and a Jcc in which case the XOR will modify the condition |
696 // a CMP and a Jcc in which case the XOR will modify the condition |
696 // flags and interfere with the Jcc. |
697 // flags and interfere with the Jcc. |
697 if (input.isNull()) { |
698 if (input.isNull()) { |
698 if (crb.mustReplaceWithNullRegister(input)) { |
699 if (moveKind == AMD64Kind.QWORD && crb.mustReplaceWithUncompressedNullRegister(input)) { |
699 masm.movq(result, crb.nullRegister); |
700 masm.movq(result, crb.uncompressedNullRegister); |
700 } else { |
701 } else { |
|
702 // Upper bits will be zeroed so this also works for narrow oops |
701 masm.movslq(result, 0); |
703 masm.movslq(result, 0); |
702 } |
704 } |
703 } else if (crb.target.inlineObjects) { |
|
704 crb.recordInlineDataInCode(input); |
|
705 masm.movq(result, 0xDEADDEADDEADDEADL, true); |
|
706 } else { |
705 } else { |
707 masm.movq(result, (AMD64Address) crb.recordDataReferenceInCode(input, 0)); |
706 if (crb.target.inlineObjects) { |
|
707 crb.recordInlineDataInCode(input); |
|
708 if (moveKind == AMD64Kind.DWORD) { |
|
709 // Support for narrow oops |
|
710 masm.movl(result, 0xDEADDEAD, true); |
|
711 } else { |
|
712 masm.movq(result, 0xDEADDEADDEADDEADL, true); |
|
713 } |
|
714 } else { |
|
715 if (moveKind == AMD64Kind.DWORD) { |
|
716 // Support for narrow oops |
|
717 masm.movl(result, (AMD64Address) crb.recordDataReferenceInCode(input, 0)); |
|
718 } else { |
|
719 masm.movq(result, (AMD64Address) crb.recordDataReferenceInCode(input, 0)); |
|
720 } |
|
721 } |
708 } |
722 } |
709 break; |
723 break; |
710 default: |
724 default: |
711 throw GraalError.shouldNotReachHere(); |
725 throw GraalError.shouldNotReachHere(); |
712 } |
726 } |
750 case Double: |
764 case Double: |
751 imm = doubleToRawLongBits(input.asDouble()); |
765 imm = doubleToRawLongBits(input.asDouble()); |
752 break; |
766 break; |
753 case Object: |
767 case Object: |
754 if (input.isNull()) { |
768 if (input.isNull()) { |
755 if (crb.mustReplaceWithNullRegister(input)) { |
769 if (crb.mustReplaceWithUncompressedNullRegister(input)) { |
756 masm.movq(dest, crb.nullRegister); |
770 masm.movq(dest, crb.uncompressedNullRegister); |
757 return; |
771 return; |
758 } |
772 } |
759 imm = 0; |
773 imm = 0; |
760 } else { |
774 } else { |
761 throw GraalError.shouldNotReachHere("Non-null object constants must be in register"); |
775 throw GraalError.shouldNotReachHere("Non-null object constants must be in a register"); |
762 } |
776 } |
763 break; |
777 break; |
764 default: |
778 default: |
765 throw GraalError.shouldNotReachHere(); |
779 throw GraalError.shouldNotReachHere(); |
766 } |
780 } |
939 this.input = input; |
953 this.input = input; |
940 } |
954 } |
941 |
955 |
942 @Override |
956 @Override |
943 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { |
957 public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { |
944 Register nullRegister = crb.nullRegister; |
958 Register nullRegister = crb.uncompressedNullRegister; |
945 if (!nullRegister.equals(Register.None)) { |
959 if (!nullRegister.equals(Register.None)) { |
946 emitConversion(asRegister(result), asRegister(input), nullRegister, masm); |
960 emitConversion(asRegister(result), asRegister(input), nullRegister, masm); |
947 } |
961 } |
948 } |
962 } |
949 |
963 |