hotspot/src/cpu/x86/vm/assembler_x86.cpp
changeset 2254 f13dda645a4b
parent 2150 0d91d17158cc
child 2255 54abdf3e1055
equal deleted inserted replaced
2253:30268d00878e 2254:f13dda645a4b
   725   if (which == end_pc_operand) {
   725   if (which == end_pc_operand) {
   726     return ip + tail_size;
   726     return ip + tail_size;
   727   }
   727   }
   728 
   728 
   729 #ifdef _LP64
   729 #ifdef _LP64
   730   assert(false, "fix locate_operand");
   730   assert(which == narrow_oop_operand && !is_64bit, "instruction is not a movl adr, imm32");
   731 #else
   731 #else
   732   assert(which == imm_operand, "instruction has only an imm field");
   732   assert(which == imm_operand, "instruction has only an imm field");
   733 #endif // LP64
   733 #endif // LP64
   734   return ip;
   734   return ip;
   735 }
   735 }
  3222 void Assembler::fyl2x() {
  3222 void Assembler::fyl2x() {
  3223   emit_byte(0xD9);
  3223   emit_byte(0xD9);
  3224   emit_byte(0xF1);
  3224   emit_byte(0xF1);
  3225 }
  3225 }
  3226 
  3226 
  3227 void Assembler::mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec, int format) {
       
  3228   InstructionMark im(this);
       
  3229   int encode = prefix_and_encode(dst->encoding());
       
  3230   emit_byte(0xB8 | encode);
       
  3231   emit_data((int)imm32, rspec, format);
       
  3232 }
       
  3233 
  3227 
  3234 #ifndef _LP64
  3228 #ifndef _LP64
  3235 
  3229 
  3236 void Assembler::incl(Register dst) {
  3230 void Assembler::incl(Register dst) {
  3237   // Don't use it directly. Use MacroAssembler::incrementl() instead.
  3231   // Don't use it directly. Use MacroAssembler::incrementl() instead.
  3247   emit_byte(0xC7);
  3241   emit_byte(0xC7);
  3248   emit_operand(rax, dst);
  3242   emit_operand(rax, dst);
  3249   emit_data((int)imm32, rspec, 0);
  3243   emit_data((int)imm32, rspec, 0);
  3250 }
  3244 }
  3251 
  3245 
       
  3246 void Assembler::mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec) {
       
  3247   InstructionMark im(this);
       
  3248   int encode = prefix_and_encode(dst->encoding());
       
  3249   emit_byte(0xB8 | encode);
       
  3250   emit_data((int)imm32, rspec, 0);
       
  3251 }
  3252 
  3252 
  3253 void Assembler::popa() { // 32bit
  3253 void Assembler::popa() { // 32bit
  3254   emit_byte(0x61);
  3254   emit_byte(0x61);
  3255 }
  3255 }
  3256 
  3256 
  3853 void Assembler::mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec) {
  3853 void Assembler::mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec) {
  3854   InstructionMark im(this);
  3854   InstructionMark im(this);
  3855   int encode = prefixq_and_encode(dst->encoding());
  3855   int encode = prefixq_and_encode(dst->encoding());
  3856   emit_byte(0xB8 | encode);
  3856   emit_byte(0xB8 | encode);
  3857   emit_data64(imm64, rspec);
  3857   emit_data64(imm64, rspec);
       
  3858 }
       
  3859 
       
  3860 void Assembler::mov_narrow_oop(Register dst, int32_t imm32, RelocationHolder const& rspec) {
       
  3861   InstructionMark im(this);
       
  3862   int encode = prefix_and_encode(dst->encoding());
       
  3863   emit_byte(0xB8 | encode);
       
  3864   emit_data((int)imm32, rspec, narrow_oop_operand);
       
  3865 }
       
  3866 
       
  3867 void Assembler::mov_narrow_oop(Address dst, int32_t imm32,  RelocationHolder const& rspec) {
       
  3868   InstructionMark im(this);
       
  3869   prefix(dst);
       
  3870   emit_byte(0xC7);
       
  3871   emit_operand(rax, dst, 4);
       
  3872   emit_data((int)imm32, rspec, narrow_oop_operand);
       
  3873 }
       
  3874 
       
  3875 void Assembler::cmp_narrow_oop(Register src1, int32_t imm32, RelocationHolder const& rspec) {
       
  3876   InstructionMark im(this);
       
  3877   int encode = prefix_and_encode(src1->encoding());
       
  3878   emit_byte(0x81);
       
  3879   emit_byte(0xF8 | encode);
       
  3880   emit_data((int)imm32, rspec, narrow_oop_operand);
       
  3881 }
       
  3882 
       
  3883 void Assembler::cmp_narrow_oop(Address src1, int32_t imm32, RelocationHolder const& rspec) {
       
  3884   InstructionMark im(this);
       
  3885   prefix(src1);
       
  3886   emit_byte(0x81);
       
  3887   emit_operand(rax, src1, 4);
       
  3888   emit_data((int)imm32, rspec, narrow_oop_operand);
  3858 }
  3889 }
  3859 
  3890 
  3860 void Assembler::movdq(XMMRegister dst, Register src) {
  3891 void Assembler::movdq(XMMRegister dst, Register src) {
  3861   // table D-1 says MMX/SSE2
  3892   // table D-1 says MMX/SSE2
  3862   NOT_LP64(assert(VM_Version::supports_sse2() || VM_Version::supports_mmx(), ""));
  3893   NOT_LP64(assert(VM_Version::supports_sse2() || VM_Version::supports_mmx(), ""));
  7708 }
  7739 }
  7709 
  7740 
  7710 void MacroAssembler::load_prototype_header(Register dst, Register src) {
  7741 void MacroAssembler::load_prototype_header(Register dst, Register src) {
  7711 #ifdef _LP64
  7742 #ifdef _LP64
  7712   if (UseCompressedOops) {
  7743   if (UseCompressedOops) {
       
  7744     assert (Universe::heap() != NULL, "java heap should be initialized");
  7713     movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
  7745     movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
  7714     movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
  7746     if (Universe::narrow_oop_shift() != 0) {
       
  7747       assert(Address::times_8 == LogMinObjAlignmentInBytes &&
       
  7748              Address::times_8 == Universe::narrow_oop_shift(), "decode alg wrong");
       
  7749       movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
       
  7750     } else {
       
  7751       movq(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
       
  7752     }
  7715   } else
  7753   } else
  7716 #endif
  7754 #endif
  7717     {
  7755   {
  7718       movptr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
  7756     movptr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
  7719       movptr(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
  7757     movptr(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
  7720     }
  7758   }
  7721 }
  7759 }
  7722 
  7760 
  7723 void MacroAssembler::store_klass(Register dst, Register src) {
  7761 void MacroAssembler::store_klass(Register dst, Register src) {
  7724 #ifdef _LP64
  7762 #ifdef _LP64
  7725   if (UseCompressedOops) {
  7763   if (UseCompressedOops) {
  7758 }
  7796 }
  7759 
  7797 
  7760 // Algorithm must match oop.inline.hpp encode_heap_oop.
  7798 // Algorithm must match oop.inline.hpp encode_heap_oop.
  7761 void MacroAssembler::encode_heap_oop(Register r) {
  7799 void MacroAssembler::encode_heap_oop(Register r) {
  7762   assert (UseCompressedOops, "should be compressed");
  7800   assert (UseCompressedOops, "should be compressed");
       
  7801   assert (Universe::heap() != NULL, "java heap should be initialized");
       
  7802   if (Universe::narrow_oop_base() == NULL) {
       
  7803     verify_oop(r, "broken oop in encode_heap_oop");
       
  7804     if (Universe::narrow_oop_shift() != 0) {
       
  7805       assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
       
  7806       shrq(r, LogMinObjAlignmentInBytes);
       
  7807     }
       
  7808     return;
       
  7809   }
  7763 #ifdef ASSERT
  7810 #ifdef ASSERT
  7764   if (CheckCompressedOops) {
  7811   if (CheckCompressedOops) {
  7765     Label ok;
  7812     Label ok;
  7766     push(rscratch1); // cmpptr trashes rscratch1
  7813     push(rscratch1); // cmpptr trashes rscratch1
  7767     cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr()));
  7814     cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
  7768     jcc(Assembler::equal, ok);
  7815     jcc(Assembler::equal, ok);
  7769     stop("MacroAssembler::encode_heap_oop: heap base corrupted?");
  7816     stop("MacroAssembler::encode_heap_oop: heap base corrupted?");
  7770     bind(ok);
  7817     bind(ok);
  7771     pop(rscratch1);
  7818     pop(rscratch1);
  7772   }
  7819   }
  7778   shrq(r, LogMinObjAlignmentInBytes);
  7825   shrq(r, LogMinObjAlignmentInBytes);
  7779 }
  7826 }
  7780 
  7827 
  7781 void MacroAssembler::encode_heap_oop_not_null(Register r) {
  7828 void MacroAssembler::encode_heap_oop_not_null(Register r) {
  7782   assert (UseCompressedOops, "should be compressed");
  7829   assert (UseCompressedOops, "should be compressed");
       
  7830   assert (Universe::heap() != NULL, "java heap should be initialized");
  7783 #ifdef ASSERT
  7831 #ifdef ASSERT
  7784   if (CheckCompressedOops) {
  7832   if (CheckCompressedOops) {
  7785     Label ok;
  7833     Label ok;
  7786     testq(r, r);
  7834     testq(r, r);
  7787     jcc(Assembler::notEqual, ok);
  7835     jcc(Assembler::notEqual, ok);
  7788     stop("null oop passed to encode_heap_oop_not_null");
  7836     stop("null oop passed to encode_heap_oop_not_null");
  7789     bind(ok);
  7837     bind(ok);
  7790   }
  7838   }
  7791 #endif
  7839 #endif
  7792   verify_oop(r, "broken oop in encode_heap_oop_not_null");
  7840   verify_oop(r, "broken oop in encode_heap_oop_not_null");
  7793   subq(r, r12_heapbase);
  7841   if (Universe::narrow_oop_base() != NULL) {
  7794   shrq(r, LogMinObjAlignmentInBytes);
  7842     subq(r, r12_heapbase);
       
  7843   }
       
  7844   if (Universe::narrow_oop_shift() != 0) {
       
  7845     assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
       
  7846     shrq(r, LogMinObjAlignmentInBytes);
       
  7847   }
  7795 }
  7848 }
  7796 
  7849 
  7797 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
  7850 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
  7798   assert (UseCompressedOops, "should be compressed");
  7851   assert (UseCompressedOops, "should be compressed");
       
  7852   assert (Universe::heap() != NULL, "java heap should be initialized");
  7799 #ifdef ASSERT
  7853 #ifdef ASSERT
  7800   if (CheckCompressedOops) {
  7854   if (CheckCompressedOops) {
  7801     Label ok;
  7855     Label ok;
  7802     testq(src, src);
  7856     testq(src, src);
  7803     jcc(Assembler::notEqual, ok);
  7857     jcc(Assembler::notEqual, ok);
  7807 #endif
  7861 #endif
  7808   verify_oop(src, "broken oop in encode_heap_oop_not_null2");
  7862   verify_oop(src, "broken oop in encode_heap_oop_not_null2");
  7809   if (dst != src) {
  7863   if (dst != src) {
  7810     movq(dst, src);
  7864     movq(dst, src);
  7811   }
  7865   }
  7812   subq(dst, r12_heapbase);
  7866   if (Universe::narrow_oop_base() != NULL) {
  7813   shrq(dst, LogMinObjAlignmentInBytes);
  7867     subq(dst, r12_heapbase);
       
  7868   }
       
  7869   if (Universe::narrow_oop_shift() != 0) {
       
  7870     assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
       
  7871     shrq(dst, LogMinObjAlignmentInBytes);
       
  7872   }
  7814 }
  7873 }
  7815 
  7874 
  7816 void  MacroAssembler::decode_heap_oop(Register r) {
  7875 void  MacroAssembler::decode_heap_oop(Register r) {
  7817   assert (UseCompressedOops, "should be compressed");
  7876   assert (UseCompressedOops, "should be compressed");
       
  7877   assert (Universe::heap() != NULL, "java heap should be initialized");
       
  7878   if (Universe::narrow_oop_base() == NULL) {
       
  7879     if (Universe::narrow_oop_shift() != 0) {
       
  7880       assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
       
  7881       shlq(r, LogMinObjAlignmentInBytes);
       
  7882     }
       
  7883     verify_oop(r, "broken oop in decode_heap_oop");
       
  7884     return;
       
  7885   }
  7818 #ifdef ASSERT
  7886 #ifdef ASSERT
  7819   if (CheckCompressedOops) {
  7887   if (CheckCompressedOops) {
  7820     Label ok;
  7888     Label ok;
  7821     push(rscratch1);
  7889     push(rscratch1);
  7822     cmpptr(r12_heapbase,
  7890     cmpptr(r12_heapbase,
  7823            ExternalAddress((address)Universe::heap_base_addr()));
  7891            ExternalAddress((address)Universe::narrow_oop_base_addr()));
  7824     jcc(Assembler::equal, ok);
  7892     jcc(Assembler::equal, ok);
  7825     stop("MacroAssembler::decode_heap_oop: heap base corrupted?");
  7893     stop("MacroAssembler::decode_heap_oop: heap base corrupted?");
  7826     bind(ok);
  7894     bind(ok);
  7827     pop(rscratch1);
  7895     pop(rscratch1);
  7828   }
  7896   }
  7842   verify_oop(r, "broken oop in decode_heap_oop");
  7910   verify_oop(r, "broken oop in decode_heap_oop");
  7843 }
  7911 }
  7844 
  7912 
  7845 void  MacroAssembler::decode_heap_oop_not_null(Register r) {
  7913 void  MacroAssembler::decode_heap_oop_not_null(Register r) {
  7846   assert (UseCompressedOops, "should only be used for compressed headers");
  7914   assert (UseCompressedOops, "should only be used for compressed headers");
       
  7915   assert (Universe::heap() != NULL, "java heap should be initialized");
  7847   // Cannot assert, unverified entry point counts instructions (see .ad file)
  7916   // Cannot assert, unverified entry point counts instructions (see .ad file)
  7848   // vtableStubs also counts instructions in pd_code_size_limit.
  7917   // vtableStubs also counts instructions in pd_code_size_limit.
  7849   // Also do not verify_oop as this is called by verify_oop.
  7918   // Also do not verify_oop as this is called by verify_oop.
  7850   assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong");
  7919   if (Universe::narrow_oop_base() == NULL) {
  7851   leaq(r, Address(r12_heapbase, r, Address::times_8, 0));
  7920     if (Universe::narrow_oop_shift() != 0) {
       
  7921       assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
       
  7922       shlq(r, LogMinObjAlignmentInBytes);
       
  7923     }
       
  7924   } else {
       
  7925       assert (Address::times_8 == LogMinObjAlignmentInBytes &&
       
  7926               Address::times_8 == Universe::narrow_oop_shift(), "decode alg wrong");
       
  7927     leaq(r, Address(r12_heapbase, r, Address::times_8, 0));
       
  7928   }
  7852 }
  7929 }
  7853 
  7930 
  7854 void  MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) {
  7931 void  MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) {
  7855   assert (UseCompressedOops, "should only be used for compressed headers");
  7932   assert (UseCompressedOops, "should only be used for compressed headers");
       
  7933   assert (Universe::heap() != NULL, "java heap should be initialized");
  7856   // Cannot assert, unverified entry point counts instructions (see .ad file)
  7934   // Cannot assert, unverified entry point counts instructions (see .ad file)
  7857   // vtableStubs also counts instructions in pd_code_size_limit.
  7935   // vtableStubs also counts instructions in pd_code_size_limit.
  7858   // Also do not verify_oop as this is called by verify_oop.
  7936   // Also do not verify_oop as this is called by verify_oop.
  7859   assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong");
  7937   if (Universe::narrow_oop_shift() != 0) {
  7860   leaq(dst, Address(r12_heapbase, src, Address::times_8, 0));
  7938     assert (Address::times_8 == LogMinObjAlignmentInBytes &&
       
  7939             Address::times_8 == Universe::narrow_oop_shift(), "decode alg wrong");
       
  7940     leaq(dst, Address(r12_heapbase, src, Address::times_8, 0));
       
  7941   } else if (dst != src) {
       
  7942     movq(dst, src);
       
  7943   }
  7861 }
  7944 }
  7862 
  7945 
  7863 void  MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
  7946 void  MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
  7864   assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
  7947   assert (UseCompressedOops, "should only be used for compressed headers");
       
  7948   assert (Universe::heap() != NULL, "java heap should be initialized");
       
  7949   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
  7865   int oop_index = oop_recorder()->find_index(obj);
  7950   int oop_index = oop_recorder()->find_index(obj);
  7866   RelocationHolder rspec = oop_Relocation::spec(oop_index);
  7951   RelocationHolder rspec = oop_Relocation::spec(oop_index);
  7867   mov_literal32(dst, oop_index, rspec, narrow_oop_operand);
  7952   mov_narrow_oop(dst, oop_index, rspec);
       
  7953 }
       
  7954 
       
  7955 void  MacroAssembler::set_narrow_oop(Address dst, jobject obj) {
       
  7956   assert (UseCompressedOops, "should only be used for compressed headers");
       
  7957   assert (Universe::heap() != NULL, "java heap should be initialized");
       
  7958   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
       
  7959   int oop_index = oop_recorder()->find_index(obj);
       
  7960   RelocationHolder rspec = oop_Relocation::spec(oop_index);
       
  7961   mov_narrow_oop(dst, oop_index, rspec);
       
  7962 }
       
  7963 
       
  7964 void  MacroAssembler::cmp_narrow_oop(Register dst, jobject obj) {
       
  7965   assert (UseCompressedOops, "should only be used for compressed headers");
       
  7966   assert (Universe::heap() != NULL, "java heap should be initialized");
       
  7967   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
       
  7968   int oop_index = oop_recorder()->find_index(obj);
       
  7969   RelocationHolder rspec = oop_Relocation::spec(oop_index);
       
  7970   Assembler::cmp_narrow_oop(dst, oop_index, rspec);
       
  7971 }
       
  7972 
       
  7973 void  MacroAssembler::cmp_narrow_oop(Address dst, jobject obj) {
       
  7974   assert (UseCompressedOops, "should only be used for compressed headers");
       
  7975   assert (Universe::heap() != NULL, "java heap should be initialized");
       
  7976   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
       
  7977   int oop_index = oop_recorder()->find_index(obj);
       
  7978   RelocationHolder rspec = oop_Relocation::spec(oop_index);
       
  7979   Assembler::cmp_narrow_oop(dst, oop_index, rspec);
  7868 }
  7980 }
  7869 
  7981 
  7870 void MacroAssembler::reinit_heapbase() {
  7982 void MacroAssembler::reinit_heapbase() {
  7871   if (UseCompressedOops) {
  7983   if (UseCompressedOops) {
  7872     movptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr()));
  7984     movptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
  7873   }
  7985   }
  7874 }
  7986 }
  7875 #endif // _LP64
  7987 #endif // _LP64
  7876 
  7988 
  7877 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
  7989 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {