8202976: Add C1 lea patching support for x86

Reviewed-by: kvn, neliasso
This commit is contained in:
Per Lidén 2018-05-14 15:42:59 +02:00
parent a6b12a847c
commit 875d55e903
11 changed files with 40 additions and 17 deletions

View File

@ -2807,7 +2807,8 @@ void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) {
} }
void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest) { void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
assert(patch_code == lir_patch_none, "Patch code not supported");
__ lea(dest->as_register_lo(), as_Address(addr->as_address_ptr())); __ lea(dest->as_register_lo(), as_Address(addr->as_address_ptr()));
} }

View File

@ -3285,7 +3285,8 @@ void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) {
} }
void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest) { void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
assert(patch_code == lir_patch_none, "Patch code not supported");
LIR_Address* addr = addr_opr->as_address_ptr(); LIR_Address* addr = addr_opr->as_address_ptr();
if (addr->index()->is_illegal()) { if (addr->index()->is_illegal()) {
jint c = addr->disp(); jint c = addr->disp();

View File

@ -2925,7 +2925,8 @@ void LIR_Assembler::on_spin_wait() {
Unimplemented(); Unimplemented();
} }
void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest) { void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
assert(patch_code == lir_patch_none, "Patch code not supported");
LIR_Address* addr = addr_opr->as_address_ptr(); LIR_Address* addr = addr_opr->as_address_ptr();
assert(addr->scale() == LIR_Address::times_1, "no scaling on this platform"); assert(addr->scale() == LIR_Address::times_1, "no scaling on this platform");
if (addr->index()->is_illegal()) { if (addr->index()->is_illegal()) {

View File

@ -2922,7 +2922,8 @@ void LIR_Assembler::on_spin_wait() {
Unimplemented(); Unimplemented();
} }
void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest) { void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
assert(patch_code == lir_patch_none, "Patch code not supported");
LIR_Address* addr = addr_opr->as_address_ptr(); LIR_Address* addr = addr_opr->as_address_ptr();
assert(addr->scale() == LIR_Address::times_1, "scaling unsupported"); assert(addr->scale() == LIR_Address::times_1, "scaling unsupported");
__ load_address(dest->as_pointer_register(), as_Address(addr)); __ load_address(dest->as_pointer_register(), as_Address(addr));

View File

@ -3195,7 +3195,7 @@ void LIR_Assembler::unpack64(LIR_Opr src, LIR_Opr dst) {
__ srl (rs, 0, rd->successor()); __ srl (rs, 0, rd->successor());
} }
void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest) { void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
const LIR_Address* addr = addr_opr->as_address_ptr(); const LIR_Address* addr = addr_opr->as_address_ptr();
assert(addr->scale() == LIR_Address::times_1, "can't handle complex addresses yet"); assert(addr->scale() == LIR_Address::times_1, "can't handle complex addresses yet");
const Register dest_reg = dest->as_pointer_register(); const Register dest_reg = dest->as_pointer_register();

View File

@ -3786,11 +3786,22 @@ void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) {
} }
void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest) { void LIR_Assembler::leal(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
assert(addr->is_address() && dest->is_register(), "check"); assert(src->is_address(), "must be an address");
Register reg; assert(dest->is_register(), "must be a register");
reg = dest->as_pointer_register();
__ lea(reg, as_Address(addr->as_address_ptr())); PatchingStub* patch = NULL;
if (patch_code != lir_patch_none) {
patch = new PatchingStub(_masm, PatchingStub::access_field_id);
}
Register reg = dest->as_pointer_register();
LIR_Address* addr = src->as_address_ptr();
__ lea(reg, as_Address(addr));
if (patch != NULL) {
patching_epilog(patch, patch_code, addr->base()->as_register(), info);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -436,6 +436,8 @@ address NativeMovRegMem::next_instruction_address() const {
case instruction_code_reg2memb: // 0x88 case instruction_code_reg2memb: // 0x88
case instruction_code_mem2regb: // 0x8a case instruction_code_mem2regb: // 0x8a
case instruction_code_lea: // 0x8d
case instruction_code_float_s: // 0xd9 fld_s a case instruction_code_float_s: // 0xd9 fld_s a
case instruction_code_float_d: // 0xdd fld_d a case instruction_code_float_d: // 0xdd fld_d a
@ -508,6 +510,9 @@ void NativeMovRegMem::verify() {
case instruction_code_xmm_lpd: // 0x12 movlpd xmm, a case instruction_code_xmm_lpd: // 0x12 movlpd xmm, a
break; break;
case instruction_code_lea: // 0x8d lea r, a
break;
default: default:
fatal ("not a mov [reg+offs], reg instruction"); fatal ("not a mov [reg+offs], reg instruction");
} }

View File

@ -354,6 +354,8 @@ class NativeMovRegMem: public NativeInstruction {
instruction_code_xmm_store = 0x11, instruction_code_xmm_store = 0x11,
instruction_code_xmm_lpd = 0x12, instruction_code_xmm_lpd = 0x12,
instruction_code_lea = 0x8d,
instruction_VEX_prefix_2bytes = Assembler::VEX_2bytes, instruction_VEX_prefix_2bytes = Assembler::VEX_2bytes,
instruction_VEX_prefix_3bytes = Assembler::VEX_3bytes, instruction_VEX_prefix_3bytes = Assembler::VEX_3bytes,
instruction_EVEX_prefix_4bytes = Assembler::EVEX_4bytes, instruction_EVEX_prefix_4bytes = Assembler::EVEX_4bytes,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -2074,7 +2074,7 @@ class LIR_List: public CompilationResourceObj {
void branch_destination(Label* lbl) { append(new LIR_OpLabel(lbl)); } void branch_destination(Label* lbl) { append(new LIR_OpLabel(lbl)); }
void negate(LIR_Opr from, LIR_Opr to) { append(new LIR_Op1(lir_neg, from, to)); } void negate(LIR_Opr from, LIR_Opr to) { append(new LIR_Op1(lir_neg, from, to)); }
void leal(LIR_Opr from, LIR_Opr result_reg) { append(new LIR_Op1(lir_leal, from, result_reg)); } void leal(LIR_Opr from, LIR_Opr result_reg, LIR_PatchCode patch_code = lir_patch_none, CodeEmitInfo* info = NULL) { append(new LIR_Op1(lir_leal, from, result_reg, T_ILLEGAL, patch_code, info)); }
// result is a stack location for old backend and vreg for UseLinearScan // result is a stack location for old backend and vreg for UseLinearScan
// stack_loc_temp is an illegal register for old backend // stack_loc_temp is an illegal register for old backend

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -276,7 +276,8 @@ void LIR_Assembler::emit_lir_list(LIR_List* list) {
// branches since they include block and stub names. Also print // branches since they include block and stub names. Also print
// patching moves since they generate funny looking code. // patching moves since they generate funny looking code.
if (op->code() == lir_branch || if (op->code() == lir_branch ||
(op->code() == lir_move && op->as_Op1()->patch_code() != lir_patch_none)) { (op->code() == lir_move && op->as_Op1()->patch_code() != lir_patch_none) ||
(op->code() == lir_leal && op->as_Op1()->patch_code() != lir_patch_none)) {
stringStream st; stringStream st;
op->print_on(&st); op->print_on(&st);
_masm->block_comment(st.as_string()); _masm->block_comment(st.as_string());
@ -554,7 +555,7 @@ void LIR_Assembler::emit_op1(LIR_Op1* op) {
break; break;
case lir_leal: case lir_leal:
leal(op->in_opr(), op->result_opr()); leal(op->in_opr(), op->result_opr(), op->patch_code(), op->info());
break; break;
case lir_null_check: { case lir_null_check: {

View File

@ -240,7 +240,7 @@ class LIR_Assembler: public CompilationResourceObj {
void align_call(LIR_Code code); void align_call(LIR_Code code);
void negate(LIR_Opr left, LIR_Opr dest); void negate(LIR_Opr left, LIR_Opr dest);
void leal(LIR_Opr left, LIR_Opr dest); void leal(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info);
void rt_call(LIR_Opr result, address dest, const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info); void rt_call(LIR_Opr result, address dest, const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info);