1 /*
  2  * Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
  3  * Copyright (c) 2012, 2026 SAP SE. All rights reserved.
  4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5  *
  6  * This code is free software; you can redistribute it and/or modify it
  7  * under the terms of the GNU General Public License version 2 only, as
  8  * published by the Free Software Foundation.
  9  *
 10  * This code is distributed in the hope that it will be useful, but WITHOUT
 11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  *
 24  */
 25 
 26 #include "asm/macroAssembler.inline.hpp"
 27 #include "c1/c1_CodeStubs.hpp"
 28 #include "c1/c1_FrameMap.hpp"
 29 #include "c1/c1_LIRAssembler.hpp"
 30 #include "c1/c1_MacroAssembler.hpp"
 31 #include "c1/c1_Runtime1.hpp"
 32 #include "classfile/javaClasses.hpp"
 33 #include "nativeInst_ppc.hpp"
 34 #include "runtime/sharedRuntime.hpp"
 35 #include "utilities/macros.hpp"
 36 #include "vmreg_ppc.inline.hpp"
 37 
 38 #define __ ce->masm()->
 39 
 40 void C1SafepointPollStub::emit_code(LIR_Assembler* ce) {
 41   if (UseSIGTRAP) {
 42     DEBUG_ONLY( __ should_not_reach_here("C1SafepointPollStub::emit_code"); )
 43   } else {
 44     __ bind(_entry);
 45     __ jump_to_polling_page_return_handler_blob(safepoint_offset());
 46   }
 47 }
 48 
 49 void RangeCheckStub::emit_code(LIR_Assembler* ce) {
 50   __ bind(_entry);
 51 
 52   if (_info->deoptimize_on_exception()) {
 53     address a = Runtime1::entry_for(StubId::c1_predicate_failed_trap_id);
 54     //__ load_const_optimized(R0, a);
 55     __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(a));
 56     __ mtctr(R0);
 57     __ bctrl();
 58     ce->add_call_info_here(_info);
 59     ce->verify_oop_map(_info);
 60     DEBUG_ONLY(__ illtrap());
 61     return;
 62   }
 63 
 64   address stub = _throw_index_out_of_bounds_exception ? Runtime1::entry_for(StubId::c1_throw_index_exception_id)
 65                                                       : Runtime1::entry_for(StubId::c1_throw_range_check_failed_id);
 66   //__ load_const_optimized(R0, stub);
 67   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub));
 68   __ mtctr(R0);
 69 
 70   Register index = R0;
 71   if (_index->is_register()) {
 72     __ extsw(index, _index->as_register());
 73   } else {
 74     __ load_const_optimized(index, _index->as_jint());
 75   }
 76   if (_array) {
 77     __ std(_array->as_pointer_register(), -8, R1_SP);
 78   }
 79   __ std(index, -16, R1_SP);
 80 
 81   __ bctrl();
 82   ce->add_call_info_here(_info);
 83   ce->verify_oop_map(_info);
 84   DEBUG_ONLY(__ illtrap());
 85 }
 86 
 87 
 88 PredicateFailedStub::PredicateFailedStub(CodeEmitInfo* info) {
 89   _info = new CodeEmitInfo(info);
 90 }
 91 
 92 void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
 93   __ bind(_entry);
 94   address a = Runtime1::entry_for(StubId::c1_predicate_failed_trap_id);
 95   //__ load_const_optimized(R0, a);
 96   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(a));
 97   __ mtctr(R0);
 98   __ bctrl();
 99   ce->add_call_info_here(_info);
100   ce->verify_oop_map(_info);
101   DEBUG_ONLY(__ illtrap());
102 }
103 
104 
105 void CounterOverflowStub::emit_code(LIR_Assembler* ce) {
106   __ bind(_entry);
107 
108   // Parameter 1: bci
109   __ load_const_optimized(R0, _bci);
110   __ std(R0, -16, R1_SP);
111 
112   // Parameter 2: Method*
113   Metadata *m = _method->as_constant_ptr()->as_metadata();
114   AddressLiteral md = __ constant_metadata_address(m); // Notify OOP recorder (don't need the relocation).
115   __ load_const_optimized(R0, md.value());
116   __ std(R0, -8, R1_SP);
117 
118   address a = Runtime1::entry_for(StubId::c1_counter_overflow_id);
119   //__ load_const_optimized(R0, a);
120   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(a));
121   __ mtctr(R0);
122   __ bctrl();
123   ce->add_call_info_here(_info);
124   ce->verify_oop_map(_info);
125 
126   __ b(_continuation);
127 }
128 
129 
130 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
131   if (_offset != -1) {
132     ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
133   }
134   __ bind(_entry);
135   address stub = Runtime1::entry_for(StubId::c1_throw_div0_exception_id);
136   //__ load_const_optimized(R0, stub);
137   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub));
138   __ mtctr(R0);
139   __ bctrl();
140   ce->add_call_info_here(_info);
141   ce->verify_oop_map(_info);
142   DEBUG_ONLY(__ illtrap());
143 }
144 
145 
146 // Implementation of LoadFlattenedArrayStub
147 
148 LoadFlattenedArrayStub::LoadFlattenedArrayStub(LIR_Opr array, LIR_Opr index, LIR_Opr result, CodeEmitInfo* info) {
149   _array = array;
150   _index = index;
151   _result = result;
152   _scratch_reg = FrameMap::R3_oop_opr;
153   _info = new CodeEmitInfo(info);
154 }
155 
156 void LoadFlattenedArrayStub::emit_code(LIR_Assembler* ce) {
157   __ bind(_entry);
158   // Pass arguments on stack.
159   __ std(_array->as_register(), -16, R1_SP);
160   __ std(_index->as_register(), -8, R1_SP);
161   address stub = Runtime1::entry_for(StubId::c1_load_flat_array_id);
162   //__ load_const_optimized(R0, stub);
163   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub));
164   __ mtctr(R0);
165   __ bctrl();
166   ce->add_call_info_here(_info);
167   ce->verify_oop_map(_info);
168   __ mr_if_needed(_result->as_register(), R3_RET);
169   __ b(_continuation);
170 }
171 
172 
173 // Implementation of StoreFlattenedArrayStub
174 
175 StoreFlattenedArrayStub::StoreFlattenedArrayStub(LIR_Opr array, LIR_Opr index, LIR_Opr value, CodeEmitInfo* info) {
176   _array = array;
177   _index = index;
178   _value = value;
179   _scratch_reg = LIR_OprFact::illegalOpr;
180   _info = new CodeEmitInfo(info);
181 }
182 
183 void StoreFlattenedArrayStub::emit_code(LIR_Assembler* ce) {
184   __ bind(_entry);
185   // Pass arguments on stack.
186   __ std(_array->as_register(), -24, R1_SP);
187   __ std(_index->as_register(), -16, R1_SP);
188   __ std(_value->as_register(), -8, R1_SP);
189   address stub = Runtime1::entry_for(StubId::c1_store_flat_array_id);
190   //__ load_const_optimized(R0, stub);
191   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub));
192   __ mtctr(R0);
193   __ bctrl();
194   ce->add_call_info_here(_info);
195   ce->verify_oop_map(_info);
196   __ b(_continuation);
197 }
198 
199 
200 // Implementation of SubstitutabilityCheckStub
201 SubstitutabilityCheckStub::SubstitutabilityCheckStub(LIR_Opr left, LIR_Opr right, CodeEmitInfo* info) {
202   _left = left;
203   _right = right;
204   _scratch_reg = FrameMap::R3_oop_opr;
205   _info = new CodeEmitInfo(info);
206 }
207 
208 void SubstitutabilityCheckStub::emit_code(LIR_Assembler* ce) {
209   __ bind(_entry);
210   // Pass arguments on stack.
211   __ std(_left->as_register(), -16, R1_SP);
212   __ std(_right->as_register(), -8, R1_SP);
213   address stub = Runtime1::entry_for(StubId::c1_substitutability_check_id);
214   //__ load_const_optimized(R0, stub);
215   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub));
216   __ mtctr(R0);
217   __ bctrl();
218   ce->add_call_info_here(_info);
219   ce->verify_oop_map(_info);
220   // Result is in R3_RET (_scratch_reg)
221   __ b(_continuation);
222 }
223 
224 
225 void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) {
226   address a;
227   if (_info->deoptimize_on_exception()) {
228     // Deoptimize, do not throw the exception, because it is probably wrong to do it here.
229     a = Runtime1::entry_for(StubId::c1_predicate_failed_trap_id);
230   } else {
231     a = Runtime1::entry_for(StubId::c1_throw_null_pointer_exception_id);
232   }
233 
234   if (ImplicitNullChecks || TrapBasedNullChecks) {
235     ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
236   }
237   __ bind(_entry);
238   //__ load_const_optimized(R0, a);
239   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(a));
240   __ mtctr(R0);
241   __ bctrl();
242   ce->add_call_info_here(_info);
243   ce->verify_oop_map(_info);
244   DEBUG_ONLY(__ illtrap());
245 }
246 
247 
248 // Implementation of SimpleExceptionStub
249 void SimpleExceptionStub::emit_code(LIR_Assembler* ce) {
250   __ bind(_entry);
251   address stub = Runtime1::entry_for(_stub);
252   //__ load_const_optimized(R0, stub);
253   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub));
254   if (_obj->is_valid()) { __ mr_if_needed(/*tmp1 in do_CheckCast*/ R4_ARG2, _obj->as_register()); }
255   __ mtctr(R0);
256   __ bctrl();
257   ce->add_call_info_here(_info);
258   DEBUG_ONLY( __ illtrap(); )
259 }
260 
261 
262 // Implementation of NewInstanceStub
263 NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, StubId stub_id) {
264   _result = result;
265   _klass = klass;
266   _klass_reg = klass_reg;
267   _info = new CodeEmitInfo(info);
268   assert(stub_id == StubId::c1_new_instance_id                 ||
269          stub_id == StubId::c1_fast_new_instance_id            ||
270          stub_id == StubId::c1_fast_new_instance_init_check_id,
271          "need new_instance id");
272   _stub_id = stub_id;
273 }
274 
275 void NewInstanceStub::emit_code(LIR_Assembler* ce) {
276   __ bind(_entry);
277 
278   address entry = Runtime1::entry_for(_stub_id);
279   //__ load_const_optimized(R0, entry);
280   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(entry));
281   __ mtctr(R0);
282   __ bctrl();
283   ce->add_call_info_here(_info);
284   ce->verify_oop_map(_info);
285   __ b(_continuation);
286 }
287 
288 
289 // Implementation of NewTypeArrayStub
290 NewTypeArrayStub::NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) {
291   _klass_reg = klass_reg;
292   _length = length;
293   _result = result;
294   _info = new CodeEmitInfo(info);
295 }
296 
297 void NewTypeArrayStub::emit_code(LIR_Assembler* ce) {
298   __ bind(_entry);
299 
300   address entry = Runtime1::entry_for(StubId::c1_new_type_array_id);
301   //__ load_const_optimized(R0, entry);
302   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(entry));
303   __ mr_if_needed(/*op->tmp1()->as_register()*/ R5_ARG3, _length->as_register()); // already sign-extended
304   __ mtctr(R0);
305   __ bctrl();
306   ce->add_call_info_here(_info);
307   ce->verify_oop_map(_info);
308   __ b(_continuation);
309 }
310 
311 
312 // Implementation of NewObjectArrayStub
313 NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result,
314                                        CodeEmitInfo* info, bool is_null_free) {
315   _klass_reg = klass_reg;
316   _length = length;
317   _result = result;
318   _info = new CodeEmitInfo(info);
319   _is_null_free = is_null_free;
320 }
321 
322 void NewObjectArrayStub::emit_code(LIR_Assembler* ce) {
323   __ bind(_entry);
324 
325   address entry = _is_null_free ? Runtime1::entry_for(StubId::c1_new_null_free_array_id)
326                                 : Runtime1::entry_for(StubId::c1_new_object_array_id);
327   //__ load_const_optimized(R0, entry);
328   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(entry));
329   __ mr_if_needed(/*op->tmp1()->as_register()*/ R5_ARG3, _length->as_register()); // already sign-extended
330   __ mtctr(R0);
331   __ bctrl();
332   ce->add_call_info_here(_info);
333   ce->verify_oop_map(_info);
334   __ b(_continuation);
335 }
336 
337 void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
338   __ bind(_entry);
339   if (_throw_ie_stub != nullptr) {
340     // When we come here, _obj_reg has already been checked to be non-null.
341     const int is_value_mask = markWord::inline_type_pattern;
342     __ ld(R0, oopDesc::mark_offset_in_bytes(), _obj_reg->as_register());
343     __ andi(R0, R0, is_value_mask);
344     __ cmpdi(CR0, R0, is_value_mask);
345     __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CR0, Assembler::equal), *_throw_ie_stub->entry());
346   }
347 
348   address stub = Runtime1::entry_for(ce->compilation()->has_fpu_code() ? StubId::c1_monitorenter_id : StubId::c1_monitorenter_nofpu_id);
349   //__ load_const_optimized(R0, stub);
350   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub));
351   __ mr_if_needed(/*scratch_opr()->as_register()*/ R4_ARG2, _obj_reg->as_register());
352   assert(_lock_reg->as_register() == R5_ARG3, "");
353   __ mtctr(R0);
354   __ bctrl();
355   ce->add_call_info_here(_info);
356   ce->verify_oop_map(_info);
357   __ b(_continuation);
358 }
359 
360 void MonitorExitStub::emit_code(LIR_Assembler* ce) {
361   __ bind(_entry);
362 
363   // lock_reg was destroyed by fast unlocking attempt => recompute it
364   ce->monitor_address(_monitor_ix, _lock_reg);
365 
366   address stub = Runtime1::entry_for(ce->compilation()->has_fpu_code() ? StubId::c1_monitorexit_id : StubId::c1_monitorexit_nofpu_id);
367   //__ load_const_optimized(R0, stub);
368   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub));
369   assert(_lock_reg->as_register() == R4_ARG2, "");
370   __ mtctr(R0);
371   __ bctrl();
372   __ b(_continuation);
373 }
374 
375 
376 // Implementation of patching:
377 // - Copy the code at given offset to an inlined buffer (first the bytes, then the number of bytes).
378 // - Replace original code with a call to the stub.
379 // At Runtime:
380 // - call to stub, jump to runtime
381 // - in runtime: preserve all registers (especially objects, i.e., source and destination object)
382 // - in runtime: after initializing class, restore original code, reexecute instruction
383 
384 int PatchingStub::_patch_info_offset = -(5 * BytesPerInstWord);
385 
386 void PatchingStub::align_patch_site(MacroAssembler* ) {
387   // Patch sites on ppc are always properly aligned.
388 }
389 
390 #ifdef ASSERT
391 inline void compare_with_patch_site(address template_start, address pc_start, int bytes_to_copy) {
392   address start = template_start;
393   for (int i = 0; i < bytes_to_copy; i++) {
394     address ptr = (address)(pc_start + i);
395     int a_byte = (*ptr) & 0xFF;
396     assert(a_byte == *start++, "should be the same code");
397   }
398 }
399 #endif
400 
401 void PatchingStub::emit_code(LIR_Assembler* ce) {
402   // copy original code here
403   assert(NativeGeneralJump::instruction_size <= _bytes_to_copy && _bytes_to_copy <= 0xFF,
404          "not enough room for call, need %d", _bytes_to_copy);
405   assert((_bytes_to_copy & 0x3) == 0, "must copy a multiple of four bytes");
406 
407   Label call_patch;
408 
409   int being_initialized_entry = __ offset();
410 
411   if (_id == load_klass_id) {
412     // Produce a copy of the load klass instruction for use by the being initialized case.
413     AddressLiteral addrlit((address)nullptr, metadata_Relocation::spec(_index));
414     __ load_const(_obj, addrlit, R0);
415     DEBUG_ONLY( compare_with_patch_site(__ code_section()->start() + being_initialized_entry, _pc_start, _bytes_to_copy); )
416   } else if (_id == load_mirror_id || _id == load_appendix_id) {
417     // Produce a copy of the load mirror instruction for use by the being initialized case.
418     AddressLiteral addrlit((address)nullptr, oop_Relocation::spec(_index));
419     __ load_const(_obj, addrlit, R0);
420     DEBUG_ONLY( compare_with_patch_site(__ code_section()->start() + being_initialized_entry, _pc_start, _bytes_to_copy); )
421   } else {
422     // Make a copy of the code which is going to be patched.
423     for (int i = 0; i < _bytes_to_copy; i++) {
424       address ptr = (address)(_pc_start + i);
425       int a_byte = (*ptr) & 0xFF;
426       __ emit_int8 (a_byte);
427     }
428   }
429 
430   address end_of_patch = __ pc();
431   int bytes_to_skip = 0;
432   if (_id == load_mirror_id) {
433     int offset = __ offset();
434     __ block_comment(" being_initialized check");
435 
436     // Static field accesses have special semantics while the class
437     // initializer is being run so we emit a test which can be used to
438     // check that this code is being executed by the initializing
439     // thread.
440     assert(_obj != noreg, "must be a valid register");
441     assert(_index >= 0, "must have oop index");
442     __ mr(R0, _obj); // spill
443     __ ld(_obj, java_lang_Class::klass_offset(), _obj);
444     __ ld(_obj, in_bytes(InstanceKlass::init_thread_offset()), _obj);
445     __ cmpd(CR0, _obj, R16_thread);
446     __ mr(_obj, R0); // restore
447     __ bne(CR0, call_patch);
448 
449     // Load_klass patches may execute the patched code before it's
450     // copied back into place so we need to jump back into the main
451     // code of the nmethod to continue execution.
452     __ b(_patch_site_continuation);
453 
454     // Make sure this extra code gets skipped.
455     bytes_to_skip += __ offset() - offset;
456   }
457 
458   // Now emit the patch record telling the runtime how to find the
459   // pieces of the patch.  We only need 3 bytes but it has to be
460   // aligned as an instruction so emit 4 bytes.
461   int sizeof_patch_record = 4;
462   bytes_to_skip += sizeof_patch_record;
463 
464   // Emit the offsets needed to find the code to patch.
465   int being_initialized_entry_offset = __ offset() - being_initialized_entry + sizeof_patch_record;
466 
467   // Emit the patch record.  We need to emit a full word, so emit an extra empty byte.
468   __ emit_int8(0);
469   __ emit_int8(being_initialized_entry_offset);
470   __ emit_int8(bytes_to_skip);
471   __ emit_int8(_bytes_to_copy);
472   address patch_info_pc = __ pc();
473   assert(patch_info_pc - end_of_patch == bytes_to_skip, "incorrect patch info");
474 
475   address entry = __ pc();
476   NativeGeneralJump::insert_unconditional((address)_pc_start, entry);
477   address target = nullptr;
478   relocInfo::relocType reloc_type = relocInfo::none;
479   switch (_id) {
480     case access_field_id:  target = Runtime1::entry_for(StubId::c1_access_field_patching_id); break;
481     case load_klass_id:    target = Runtime1::entry_for(StubId::c1_load_klass_patching_id);
482                            reloc_type = relocInfo::metadata_type; break;
483     case load_mirror_id:   target = Runtime1::entry_for(StubId::c1_load_mirror_patching_id);
484                            reloc_type = relocInfo::oop_type; break;
485     case load_appendix_id: target = Runtime1::entry_for(StubId::c1_load_appendix_patching_id);
486                            reloc_type = relocInfo::oop_type; break;
487     default: ShouldNotReachHere();
488   }
489   __ bind(call_patch);
490 
491   __ block_comment("patch entry point");
492   //__ load_const(R0, target); + mtctr + bctrl must have size -_patch_info_offset
493   __ load_const32(R0, MacroAssembler::offset_to_global_toc(target));
494   __ add(R0, R29_TOC, R0);
495   __ mtctr(R0);
496   __ bctrl();
497   assert(_patch_info_offset == (patch_info_pc - __ pc()), "must not change");
498   ce->add_call_info_here(_info);
499   __ b(_patch_site_entry);
500   if (_id == load_klass_id || _id == load_mirror_id || _id == load_appendix_id) {
501     CodeSection* cs = __ code_section();
502     address pc = (address)_pc_start;
503     RelocIterator iter(cs, pc, pc + 1);
504     relocInfo::change_reloc_info_for_address(&iter, (address) pc, reloc_type, relocInfo::none);
505   }
506 }
507 
508 
509 void DeoptimizeStub::emit_code(LIR_Assembler* ce) {
510   __ bind(_entry);
511   address stub = Runtime1::entry_for(StubId::c1_deoptimize_id);
512   //__ load_const_optimized(R0, stub);
513   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub));
514   __ mtctr(R0);
515 
516   __ load_const_optimized(R0, _trap_request); // Pass trap request in R0.
517   __ bctrl();
518   ce->add_call_info_here(_info);
519   DEBUG_ONLY(__ illtrap());
520 }
521 
522 
523 void ArrayCopyStub::emit_code(LIR_Assembler* ce) {
524   //---------------slow case: call to native-----------------
525   __ bind(_entry);
526   __ mr(R3_ARG1, src()->as_register());
527   __ extsw(R4_ARG2, src_pos()->as_register());
528   __ mr(R5_ARG3, dst()->as_register());
529   __ extsw(R6_ARG4, dst_pos()->as_register());
530   __ extsw(R7_ARG5, length()->as_register());
531 
532   ce->emit_static_call_stub();
533   if (ce->compilation()->bailed_out()) {
534     return; // CodeCache is full
535   }
536 
537   AddressLiteral resolve(SharedRuntime::get_resolve_static_call_stub(),
538                          relocInfo::static_call_type);
539   address call_pc = __ trampoline_call(resolve);
540   if (call_pc == nullptr) {
541     ce->bailout("const/stub overflow in call with trampoline");
542     return;
543   }
544   ce->add_call_info_here(info());
545   ce->verify_oop_map(info());
546 
547 #ifndef PRODUCT
548   if (PrintC1Statistics) {
549     const address counter = (address)&Runtime1::_arraycopy_slowcase_cnt;
550     const Register tmp = R3, tmp2 = R4;
551     int simm16_offs = __ load_const_optimized(tmp, counter, tmp2, true);
552     __ lwz(tmp2, simm16_offs, tmp);
553     __ addi(tmp2, tmp2, 1);
554     __ stw(tmp2, simm16_offs, tmp);
555   }
556 #endif
557 
558   __ b(_continuation);
559 }
560 
561 #undef __