< prev index next >

src/hotspot/share/c1/c1_LIR.cpp

Print this page
@@ -1,7 +1,7 @@
  /*
-  * 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.

@@ -186,10 +186,13 @@
  
  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(),

@@ -236,30 +239,42 @@
  #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)
  {

@@ -277,17 +292,17 @@
    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();
    }
  }
  
  

@@ -511,10 +526,19 @@
      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;

@@ -599,10 +623,25 @@
  
      // 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");

@@ -610,10 +649,11 @@
  
        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

@@ -1040,10 +1080,16 @@
  
  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());
    }

@@ -1076,10 +1122,14 @@
  #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) {

@@ -1093,10 +1143,42 @@
    _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();
  

@@ -1665,10 +1747,11 @@
       // 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;

@@ -1823,10 +1906,14 @@
  }
  
  // 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);

@@ -1909,11 +1996,15 @@
    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(" "); }

@@ -1960,10 +2051,21 @@
    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 >