Mercurial > hg > graal-compiler
comparison src/cpu/ppc/vm/macroAssembler_ppc.cpp @ 14451:b858620b0081
8031319: PPC64: Some fixes in ppc and aix coding.
Reviewed-by: kvn
author | goetz |
---|---|
date | Tue, 07 Jan 2014 17:24:59 +0100 |
parents | 67fa91961822 |
children | e5e8aa897002 |
comparison
equal
deleted
inserted
replaced
14450:c3efa8868779 | 14451:b858620b0081 |
---|---|
204 const int inst2 = *(int *)inst2_addr; | 204 const int inst2 = *(int *)inst2_addr; |
205 | 205 |
206 // The relocation points to the second instruction, the ori, | 206 // The relocation points to the second instruction, the ori, |
207 // and the ori reads and writes the same register dst. | 207 // and the ori reads and writes the same register dst. |
208 const int dst = inv_rta_field(inst2); | 208 const int dst = inv_rta_field(inst2); |
209 assert(is_ori(inst2) && inv_rs_field(inst2) == dst, "must be addi reading and writing dst"); | 209 assert(is_ori(inst2) && inv_rs_field(inst2) == dst, "must be ori reading and writing dst"); |
210 // Now, find the preceding addis which writes to dst. | 210 // Now, find the preceding addis which writes to dst. |
211 int inst1 = 0; | 211 int inst1 = 0; |
212 address inst1_addr = inst2_addr - BytesPerInstWord; | 212 address inst1_addr = inst2_addr - BytesPerInstWord; |
213 bool inst1_found = false; | 213 bool inst1_found = false; |
214 while (inst1_addr >= bound) { | 214 while (inst1_addr >= bound) { |
220 | 220 |
221 int xc = (data >> 16) & 0xffff; | 221 int xc = (data >> 16) & 0xffff; |
222 int xd = (data >> 0) & 0xffff; | 222 int xd = (data >> 0) & 0xffff; |
223 | 223 |
224 set_imm((int *)inst1_addr, (short)(xc)); // see enc_load_con_narrow_hi/_lo | 224 set_imm((int *)inst1_addr, (short)(xc)); // see enc_load_con_narrow_hi/_lo |
225 set_imm((int *)inst2_addr, (short)(xd)); | 225 set_imm((int *)inst2_addr, (xd)); // unsigned int |
226 | |
227 return (int)((intptr_t)inst2_addr - (intptr_t)inst1_addr); | 226 return (int)((intptr_t)inst2_addr - (intptr_t)inst1_addr); |
228 } | 227 } |
229 | 228 |
230 // Get compressed oop or klass constant. | 229 // Get compressed oop or klass constant. |
231 narrowOop MacroAssembler::get_narrow_oop(address a, address bound) { | 230 narrowOop MacroAssembler::get_narrow_oop(address a, address bound) { |
235 const int inst2 = *(int *)inst2_addr; | 234 const int inst2 = *(int *)inst2_addr; |
236 | 235 |
237 // The relocation points to the second instruction, the ori, | 236 // The relocation points to the second instruction, the ori, |
238 // and the ori reads and writes the same register dst. | 237 // and the ori reads and writes the same register dst. |
239 const int dst = inv_rta_field(inst2); | 238 const int dst = inv_rta_field(inst2); |
240 assert(is_ori(inst2) && inv_rs_field(inst2) == dst, "must be addi reading and writing dst"); | 239 assert(is_ori(inst2) && inv_rs_field(inst2) == dst, "must be ori reading and writing dst"); |
241 // Now, find the preceding lis which writes to dst. | 240 // Now, find the preceding lis which writes to dst. |
242 int inst1 = 0; | 241 int inst1 = 0; |
243 address inst1_addr = inst2_addr - BytesPerInstWord; | 242 address inst1_addr = inst2_addr - BytesPerInstWord; |
244 bool inst1_found = false; | 243 bool inst1_found = false; |
245 | 244 |
994 // so do a full call-c here. | 993 // so do a full call-c here. |
995 load_const(R11, (address)fd, R0); | 994 load_const(R11, (address)fd, R0); |
996 | 995 |
997 bool has_env = (fd != NULL && fd->env() != NULL); | 996 bool has_env = (fd != NULL && fd->env() != NULL); |
998 return branch_to(R11, /*and_link=*/true, | 997 return branch_to(R11, /*and_link=*/true, |
999 /*save toc=*/false, | 998 /*save toc=*/false, |
1000 /*restore toc=*/false, | 999 /*restore toc=*/false, |
1001 /*load toc=*/true, | 1000 /*load toc=*/true, |
1002 /*load env=*/has_env); | 1001 /*load env=*/has_env); |
1003 } else { | 1002 } else { |
1004 // It's a friend function. Load the entry point and don't care about | 1003 // It's a friend function. Load the entry point and don't care about |
1005 // toc and env. Use an optimizable call instruction, but ensure the | 1004 // toc and env. Use an optimizable call instruction, but ensure the |
1006 // same code-size as in the case of a non-friend function. | 1005 // same code-size as in the case of a non-friend function. |
1007 nop(); | 1006 nop(); |
1018 || !fd->is_friend_function()) { | 1017 || !fd->is_friend_function()) { |
1019 // It's not a friend function as defined by class FunctionDescriptor, | 1018 // It's not a friend function as defined by class FunctionDescriptor, |
1020 // so do a full call-c here. | 1019 // so do a full call-c here. |
1021 load_const(R11, (address)fd, R0); | 1020 load_const(R11, (address)fd, R0); |
1022 return branch_to(R11, /*and_link=*/true, | 1021 return branch_to(R11, /*and_link=*/true, |
1023 /*save toc=*/false, | 1022 /*save toc=*/false, |
1024 /*restore toc=*/false, | 1023 /*restore toc=*/false, |
1025 /*load toc=*/true, | 1024 /*load toc=*/true, |
1026 /*load env=*/true); | 1025 /*load env=*/true); |
1027 } else { | 1026 } else { |
1028 // it's a friend function, load the entry point and don't care about | 1027 // it's a friend function, load the entry point and don't care about |
1029 // toc and env. | 1028 // toc and env. |
1030 address dest = fd->entry(); | 1029 address dest = fd->entry(); |
1031 if (is_within_range_of_b(dest, pc())) { | 1030 if (is_within_range_of_b(dest, pc())) { |
1965 std(displaced_header, BasicLock::displaced_header_offset_in_bytes(), box); | 1964 std(displaced_header, BasicLock::displaced_header_offset_in_bytes(), box); |
1966 | 1965 |
1967 // Must fence, otherwise, preceding store(s) may float below cmpxchg. | 1966 // Must fence, otherwise, preceding store(s) may float below cmpxchg. |
1968 // Compare object markOop with mark and if equal exchange scratch1 with object markOop. | 1967 // Compare object markOop with mark and if equal exchange scratch1 with object markOop. |
1969 // CmpxchgX sets cr_reg to cmpX(current, displaced). | 1968 // CmpxchgX sets cr_reg to cmpX(current, displaced). |
1969 membar(Assembler::StoreStore); | |
1970 cmpxchgd(/*flag=*/flag, | 1970 cmpxchgd(/*flag=*/flag, |
1971 /*current_value=*/current_header, | 1971 /*current_value=*/current_header, |
1972 /*compare_value=*/displaced_header, | 1972 /*compare_value=*/displaced_header, |
1973 /*exchange_value=*/box, | 1973 /*exchange_value=*/box, |
1974 /*where=*/oop, | 1974 /*where=*/oop, |
1975 MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq, | 1975 MacroAssembler::MemBarAcq, |
1976 MacroAssembler::cmpxchgx_hint_acquire_lock(), | 1976 MacroAssembler::cmpxchgx_hint_acquire_lock(), |
1977 noreg, | 1977 noreg, |
1978 &cas_failed); | 1978 &cas_failed); |
1979 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); | 1979 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); |
1980 | 1980 |
2156 void MacroAssembler::card_table_write(jbyte* byte_map_base, Register Rtmp, Register Robj) { | 2156 void MacroAssembler::card_table_write(jbyte* byte_map_base, Register Rtmp, Register Robj) { |
2157 assert_different_registers(Robj, Rtmp, R0); | 2157 assert_different_registers(Robj, Rtmp, R0); |
2158 load_const_optimized(Rtmp, (address)byte_map_base, R0); | 2158 load_const_optimized(Rtmp, (address)byte_map_base, R0); |
2159 srdi(Robj, Robj, CardTableModRefBS::card_shift); | 2159 srdi(Robj, Robj, CardTableModRefBS::card_shift); |
2160 li(R0, 0); // dirty | 2160 li(R0, 0); // dirty |
2161 if (UseConcMarkSweepGC) release(); | 2161 if (UseConcMarkSweepGC) membar(Assembler::StoreStore); |
2162 stbx(R0, Rtmp, Robj); | 2162 stbx(R0, Rtmp, Robj); |
2163 } | 2163 } |
2164 | 2164 |
2165 #ifndef SERIALGC | 2165 #ifndef SERIALGC |
2166 | 2166 |
2397 std(R0, in_bytes(JavaThread::vm_result_2_offset()), R16_thread); | 2397 std(R0, in_bytes(JavaThread::vm_result_2_offset()), R16_thread); |
2398 } | 2398 } |
2399 | 2399 |
2400 | 2400 |
2401 void MacroAssembler::encode_klass_not_null(Register dst, Register src) { | 2401 void MacroAssembler::encode_klass_not_null(Register dst, Register src) { |
2402 if (src == noreg) src = dst; | 2402 Register current = (src != noreg) ? src : dst; // Klass is in dst if no src provided. |
2403 if (Universe::narrow_klass_base() != 0) { | 2403 if (Universe::narrow_klass_base() != 0) { |
2404 load_const(R0, Universe::narrow_klass_base()); | 2404 load_const(R0, Universe::narrow_klass_base(), (dst != current) ? dst : noreg); // Use dst as temp if it is free. |
2405 sub(dst, src, R0); | 2405 sub(dst, current, R0); |
2406 } | 2406 current = dst; |
2407 if (Universe::narrow_klass_shift() != 0 || | 2407 } |
2408 Universe::narrow_klass_base() == 0 && src != dst) { // Move required. | 2408 if (Universe::narrow_klass_shift() != 0) { |
2409 srdi(dst, src, Universe::narrow_klass_shift()); | 2409 srdi(dst, current, Universe::narrow_klass_shift()); |
2410 } | 2410 current = dst; |
2411 } | |
2412 mr_if_needed(dst, current); // Move may be required. | |
2411 } | 2413 } |
2412 | 2414 |
2413 void MacroAssembler::store_klass(Register dst_oop, Register klass, Register ck) { | 2415 void MacroAssembler::store_klass(Register dst_oop, Register klass, Register ck) { |
2414 if (UseCompressedClassPointers) { | 2416 if (UseCompressedClassPointers) { |
2415 encode_klass_not_null(ck, klass); | 2417 encode_klass_not_null(ck, klass); |