< prev index next > src/hotspot/share/c1/c1_LIR.cpp
Print this page
/*
- * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
void LIR_Op2::verify() const {
#ifdef ASSERT
switch (code()) {
case lir_cmove:
+ #ifdef RISCV
+ assert(false, "lir_cmove is LIR_Op4 on RISCV");
+ #endif
case lir_xchg:
break;
default:
assert(!result_opr()->is_register() || !result_opr()->is_oop_register(),
#endif
}
LIR_OpBranch::LIR_OpBranch(LIR_Condition cond, BlockBegin* block)
+ #ifdef RISCV
+ : LIR_Op2(lir_branch, cond, LIR_OprFact::illegalOpr, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL)
+ #else
: LIR_Op(lir_branch, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL)
, _cond(cond)
+ #endif
, _label(block->label())
, _block(block)
, _ublock(NULL)
, _stub(NULL) {
}
LIR_OpBranch::LIR_OpBranch(LIR_Condition cond, CodeStub* stub) :
+ #ifdef RISCV
+ LIR_Op2(lir_branch, cond, LIR_OprFact::illegalOpr, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL)
+ #else
LIR_Op(lir_branch, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL)
, _cond(cond)
+ #endif
, _label(stub->entry())
, _block(NULL)
, _ublock(NULL)
, _stub(stub) {
}
LIR_OpBranch::LIR_OpBranch(LIR_Condition cond, BlockBegin* block, BlockBegin* ublock)
+ #ifdef RISCV
+ : LIR_Op2(lir_cond_float_branch, cond, LIR_OprFact::illegalOpr, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL)
+ #else
: LIR_Op(lir_cond_float_branch, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL)
, _cond(cond)
+ #endif
, _label(block->label())
, _block(block)
, _ublock(ublock)
, _stub(NULL)
{
assert(_ublock != NULL, "must have old block");
_ublock = b;
}
void LIR_OpBranch::negate_cond() {
- switch (_cond) {
- case lir_cond_equal: _cond = lir_cond_notEqual; break;
- case lir_cond_notEqual: _cond = lir_cond_equal; break;
- case lir_cond_less: _cond = lir_cond_greaterEqual; break;
- case lir_cond_lessEqual: _cond = lir_cond_greater; break;
- case lir_cond_greaterEqual: _cond = lir_cond_less; break;
- case lir_cond_greater: _cond = lir_cond_lessEqual; break;
+ switch (cond()) {
+ case lir_cond_equal: set_cond(lir_cond_notEqual); break;
+ case lir_cond_notEqual: set_cond(lir_cond_equal); break;
+ case lir_cond_less: set_cond(lir_cond_greaterEqual); break;
+ case lir_cond_lessEqual: set_cond(lir_cond_greater); break;
+ case lir_cond_greaterEqual: set_cond(lir_cond_less); break;
+ case lir_cond_greater: set_cond(lir_cond_lessEqual); break;
default: ShouldNotReachHere();
}
}
case lir_cond_float_branch: // may have info, input and result register always invalid
{
assert(op->as_OpBranch() != NULL, "must be");
LIR_OpBranch* opBranch = (LIR_OpBranch*)op;
+ #ifdef RISCV
+ assert(opBranch->_tmp1->is_illegal() && opBranch->_tmp2->is_illegal() &&
+ opBranch->_tmp3->is_illegal() && opBranch->_tmp4->is_illegal() &&
+ opBranch->_tmp5->is_illegal(), "not used");
+
+ if (opBranch->_opr1->is_valid()) do_input(opBranch->_opr1);
+ if (opBranch->_opr2->is_valid()) do_input(opBranch->_opr2);
+ #endif
+
if (opBranch->_info != NULL) do_info(opBranch->_info);
assert(opBranch->_result->is_illegal(), "not used");
if (opBranch->_stub != NULL) opBranch->stub()->visit(this);
break;
// special handling for cmove: right input operand must not be equal
// to the result operand, otherwise the backend fails
case lir_cmove:
{
+ #ifdef RISCV
+ assert(op->as_Op4() != NULL, "must be");
+ LIR_Op4* op4 = (LIR_Op4*)op;
+
+ assert(op4->_info == NULL && op4->_tmp1->is_illegal() && op4->_tmp2->is_illegal() &&
+ op4->_tmp3->is_illegal() && op4->_tmp4->is_illegal() && op4->_tmp5->is_illegal(), "not used");
+ assert(op4->_opr1->is_valid() && op4->_opr2->is_valid() && op4->_result->is_valid(), "used");
+
+ do_input(op4->_opr1);
+ do_input(op4->_opr2);
+ if (op4->_opr3->is_valid()) do_input(op4->_opr3);
+ if (op4->_opr4->is_valid()) do_input(op4->_opr4);
+ do_temp(op4->_opr2);
+ do_output(op4->_result);
+ #else
assert(op->as_Op2() != NULL, "must be");
LIR_Op2* op2 = (LIR_Op2*)op;
assert(op2->_info == NULL && op2->_tmp1->is_illegal() && op2->_tmp2->is_illegal() &&
op2->_tmp3->is_illegal() && op2->_tmp4->is_illegal() && op2->_tmp5->is_illegal(), "not used");
do_input(op2->_opr1);
do_input(op2->_opr2);
do_temp(op2->_opr2);
do_output(op2->_result);
+ #endif
break;
}
// vspecial handling for strict operations: register input operands
void LIR_Op3::emit_code(LIR_Assembler* masm) {
masm->emit_op3(this);
}
+ #ifdef RISCV
+ void LIR_Op4::emit_code(LIR_Assembler* masm) {
+ masm->emit_op4(this);
+ }
+ #endif
+
void LIR_OpLock::emit_code(LIR_Assembler* masm) {
masm->emit_lock(this);
if (stub()) {
masm->append_code_stub(stub());
}
#endif
#ifdef ASSERT
, _file(NULL)
, _line(0)
#endif
+ #ifdef RISCV
+ , _cmp_opr1(LIR_OprFact::illegalOpr)
+ , _cmp_opr2(LIR_OprFact::illegalOpr)
+ #endif
{ }
#ifdef ASSERT
void LIR_List::set_file_and_line(const char * file, int line) {
_file = f;
_line = line;
}
#endif
+ #ifdef RISCV
+ void LIR_List::set_cmp_oprs(LIR_Op* op) {
+ switch (op->code()) {
+ case lir_cmp:
+ _cmp_opr1 = op->as_Op2()->in_opr1();
+ _cmp_opr2 = op->as_Op2()->in_opr2();
+ break;
+ case lir_branch: // fall through
+ case lir_cond_float_branch:
+ assert(op->as_OpBranch()->cond() == lir_cond_always ||
+ (_cmp_opr1 != LIR_OprFact::illegalOpr && _cmp_opr2 != LIR_OprFact::illegalOpr),
+ "conditional branches must have legal operands");
+ if (op->as_OpBranch()->cond() != lir_cond_always) {
+ op->as_Op2()->set_in_opr1(_cmp_opr1);
+ op->as_Op2()->set_in_opr2(_cmp_opr2);
+ }
+ break;
+ case lir_cmove:
+ op->as_Op4()->set_in_opr3(_cmp_opr1);
+ op->as_Op4()->set_in_opr4(_cmp_opr2);
+ break;
+ #if INCLUDE_ZGC
+ case lir_zloadbarrier_test:
+ _cmp_opr1 = FrameMap::as_opr(t1);
+ _cmp_opr2 = LIR_OprFact::intConst(0);
+ break;
+ #endif
+ default:
+ break;
+ }
+ }
+ #endif
void LIR_List::append(LIR_InsertionBuffer* buffer) {
assert(this == buffer->lir_list(), "wrong lir list");
const int n = _operations.length();
// LIR_Op2
case lir_cmp: s = "cmp"; break;
case lir_cmp_l2i: s = "cmp_l2i"; break;
case lir_ucmp_fd2i: s = "ucomp_fd2i"; break;
case lir_cmp_fd2i: s = "comp_fd2i"; break;
+ // cmove is a LIR_Op4 on RISCV
case lir_cmove: s = "cmove"; break;
case lir_add: s = "add"; break;
case lir_sub: s = "sub"; break;
case lir_mul: s = "mul"; break;
case lir_div: s = "div"; break;
}
// LIR_OpBranch
void LIR_OpBranch::print_instr(outputStream* out) const {
print_condition(out, cond()); out->print(" ");
+ #ifdef RISCV
+ in_opr1()->print(out); out->print(" ");
+ in_opr2()->print(out); out->print(" ");
+ #endif
if (block() != NULL) {
out->print("[B%d] ", block()->block_id());
} else if (stub() != NULL) {
out->print("[");
stub()->print_name(out);
result_opr()->print(out); out->print(" ");
}
// LIR_Op2
void LIR_Op2::print_instr(outputStream* out) const {
+ #ifdef RISCV
+ if (code() == lir_cmp || code() == lir_branch || code() == lir_cond_float_branch) {
+ #else
if (code() == lir_cmove || code() == lir_cmp) {
+ #endif
print_condition(out, condition()); out->print(" ");
}
in_opr1()->print(out); out->print(" ");
in_opr2()->print(out); out->print(" ");
if (tmp1_opr()->is_valid()) { tmp1_opr()->print(out); out->print(" "); }
in_opr2()->print(out); out->print(" ");
in_opr3()->print(out); out->print(" ");
result_opr()->print(out);
}
+ #ifdef RISCV
+ // LIR_Op4
+ void LIR_Op4::print_instr(outputStream* out) const {
+ print_condition(out, condition()); out->print(" ");
+ in_opr1()->print(out); out->print(" ");
+ in_opr2()->print(out); out->print(" ");
+ in_opr3()->print(out); out->print(" ");
+ in_opr4()->print(out); out->print(" ");
+ result_opr()->print(out);
+ }
+ #endif
void LIR_OpLock::print_instr(outputStream* out) const {
hdr_opr()->print(out); out->print(" ");
obj_opr()->print(out); out->print(" ");
lock_opr()->print(out); out->print(" ");
< prev index next >