diff -r 2a33b32dd03c -r fd13a567f179 src/cpu/mips/vm/macroAssembler_mips.cpp --- a/src/cpu/mips/vm/macroAssembler_mips.cpp Thu May 24 19:24:53 2018 +0800 +++ b/src/cpu/mips/vm/macroAssembler_mips.cpp Thu May 24 19:26:50 2018 +0800 @@ -95,6 +95,7 @@ void MacroAssembler::pd_patch_instruction(address branch, address target) { jint& stub_inst = *(jint*) branch; + jint *pc = (jint *)branch; /* * move(AT, RA); // dadd @@ -106,8 +107,7 @@ move(RA, AT); jr(T9); */ - if(special(stub_inst) == dadd_op) { - jint *pc = (jint *)branch; + if((opcode(stub_inst) == special_op) && (special(stub_inst) == dadd_op)) { assert(opcode(pc[3]) == lui_op && opcode(pc[4]) == ori_op @@ -135,6 +135,14 @@ __ nop(); } return; + } else if (special(pc[4]) == jr_op + && opcode(pc[4]) == special_op + && (((opcode(pc[0]) == lui_op) || opcode(pc[0]) == daddiu_op) || (opcode(pc[0]) == ori_op))) { + + CodeBuffer cb(branch, 4 * 4); + MacroAssembler masm(&cb); + masm.patchable_set48(T9, (long)(target)); + return; } #ifndef PRODUCT @@ -332,6 +340,50 @@ } } +void MacroAssembler::beq_long(Register rs, Register rt, Label& L) { + Label not_taken; + + bne(rs, rt, not_taken); + nop(); + + jmp_far(L); + + bind(not_taken); +} + +void MacroAssembler::bne_long(Register rs, Register rt, Label& L) { + Label not_taken; + + beq(rs, rt, not_taken); + nop(); + + jmp_far(L); + + bind(not_taken); +} + +void MacroAssembler::bc1t_long(Label& L) { + Label not_taken; + + bc1f(not_taken); + nop(); + + jmp_far(L); + + bind(not_taken); +} + +void MacroAssembler::bc1f_long(Label& L) { + Label not_taken; + + bc1t(not_taken); + nop(); + + jmp_far(L); + + bind(not_taken); +} + void MacroAssembler::b_far(Label& L) { if (L.is_bound()) { b_far(target(L)); @@ -747,6 +799,26 @@ } } +void MacroAssembler::jmp_far(Label& L) { + if (L.is_bound()) { + address entry = target(L); + assert(entry != NULL, "jmp most probably wrong"); + InstructionMark im(this); + + relocate(relocInfo::internal_word_type); + patchable_set48(T9, (long)entry); + } else { + InstructionMark im(this); + L.add_patch_at(code(), locator()); + + relocate(relocInfo::internal_word_type); + patchable_set48(T9, (long)pc()); + } + + jr(T9); + nop(); +} + void MacroAssembler::call(address entry) { // c/c++ code assume T9 is entry point, so we just always move entry to t9 // maybe there is some more graceful method to handle this. FIXME