< prev index next >

src/hotspot/share/c1/c1_LIR.hpp

Print this page
@@ -866,10 +866,11 @@
  class      LIR_OpRoundFP;
  class    LIR_Op2;
  class    LIR_OpDelay;
  class    LIR_Op3;
  class      LIR_OpAllocArray;
+ class    LIR_Op4;
  class    LIR_OpCall;
  class      LIR_OpJavaCall;
  class      LIR_OpRTCall;
  class    LIR_OpArrayCopy;
  class    LIR_OpUpdateCRC32;

@@ -909,26 +910,25 @@
        , lir_push
        , lir_pop
        , lir_null_check
        , lir_return
        , lir_leal
-       , lir_branch
-       , lir_cond_float_branch
        , lir_move
        , lir_convert
        , lir_alloc_object
        , lir_monaddr
        , lir_roundfp
        , lir_safepoint
        , lir_unwind
    , end_op1
    , begin_op2
+       , lir_branch
+       , lir_cond_float_branch
        , lir_cmp
        , lir_cmp_l2i
        , lir_ucmp_fd2i
        , lir_cmp_fd2i
-       , lir_cmove
        , lir_add
        , lir_sub
        , lir_mul
        , lir_div
        , lir_rem

@@ -952,10 +952,13 @@
        , lir_idiv
        , lir_irem
        , lir_fmad
        , lir_fmaf
    , end_op3
+   , begin_op4
+       , lir_cmove
+   , end_op4
    , begin_opJavaCall
        , lir_static_call
        , lir_optvirtual_call
        , lir_icvirtual_call
        , lir_dynamic_call

@@ -1123,10 +1126,11 @@
    virtual LIR_OpConvert* as_OpConvert() { return NULL; }
    virtual LIR_Op0* as_Op0() { return NULL; }
    virtual LIR_Op1* as_Op1() { return NULL; }
    virtual LIR_Op2* as_Op2() { return NULL; }
    virtual LIR_Op3* as_Op3() { return NULL; }
+   virtual LIR_Op4* as_Op4() { return NULL; }
    virtual LIR_OpArrayCopy* as_OpArrayCopy() { return NULL; }
    virtual LIR_OpUpdateCRC32* as_OpUpdateCRC32() { return NULL; }
    virtual LIR_OpTypeCheck* as_OpTypeCheck() { return NULL; }
    virtual LIR_OpCompareAndSwap* as_OpCompareAndSwap() { return NULL; }
    virtual LIR_OpProfileCall* as_OpProfileCall() { return NULL; }

@@ -1395,49 +1399,10 @@
  
    virtual void verify() const;
  };
  
  
- class LIR_OpBranch: public LIR_Op {
-  friend class LIR_OpVisitState;
- 
-  private:
-   LIR_Condition _cond;
-   Label*        _label;
-   BlockBegin*   _block;  // if this is a branch to a block, this is the block
-   BlockBegin*   _ublock; // if this is a float-branch, this is the unorderd block
-   CodeStub*     _stub;   // if this is a branch to a stub, this is the stub
- 
-  public:
-   LIR_OpBranch(LIR_Condition cond, Label* lbl)
-     : LIR_Op(lir_branch, LIR_OprFact::illegalOpr, (CodeEmitInfo*) NULL)
-     , _cond(cond)
-     , _label(lbl)
-     , _block(NULL)
-     , _ublock(NULL)
-     , _stub(NULL) { }
- 
-   LIR_OpBranch(LIR_Condition cond, BlockBegin* block);
-   LIR_OpBranch(LIR_Condition cond, CodeStub* stub);
- 
-   // for unordered comparisons
-   LIR_OpBranch(LIR_Condition cond, BlockBegin* block, BlockBegin* ublock);
- 
-   LIR_Condition cond()        const              { return _cond;        }
-   Label*        label()       const              { return _label;       }
-   BlockBegin*   block()       const              { return _block;       }
-   BlockBegin*   ublock()      const              { return _ublock;      }
-   CodeStub*     stub()        const              { return _stub;       }
- 
-   void          change_block(BlockBegin* b);
-   void          change_ublock(BlockBegin* b);
-   void          negate_cond();
- 
-   virtual void emit_code(LIR_Assembler* masm);
-   virtual LIR_OpBranch* as_OpBranch() { return this; }
-   virtual void print_instr(outputStream* out) const PRODUCT_RETURN;
- };
  
  class LIR_OpReturn: public LIR_Op1 {
   friend class LIR_OpVisitState;
  
   private:

@@ -1607,23 +1572,23 @@
    LIR_Condition _condition;
  
    void verify() const;
  
   public:
-   LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, CodeEmitInfo* info = NULL)
+   LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, CodeEmitInfo* info = NULL, BasicType type = T_ILLEGAL)
      : LIR_Op(code, LIR_OprFact::illegalOpr, info)
      , _fpu_stack_size(0)
      , _opr1(opr1)
      , _opr2(opr2)
-     , _type(T_ILLEGAL)
+     , _type(type)
      , _tmp1(LIR_OprFact::illegalOpr)
      , _tmp2(LIR_OprFact::illegalOpr)
      , _tmp3(LIR_OprFact::illegalOpr)
      , _tmp4(LIR_OprFact::illegalOpr)
      , _tmp5(LIR_OprFact::illegalOpr)
      , _condition(condition) {
-     assert(code == lir_cmp || code == lir_assert, "code check");
+     assert(code == lir_cmp || code == lir_branch || code == lir_cond_float_branch || code == lir_assert, "code check");
    }
  
    LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type)
      : LIR_Op(code, result, NULL)
      , _fpu_stack_size(0)

@@ -1651,11 +1616,11 @@
      , _tmp2(LIR_OprFact::illegalOpr)
      , _tmp3(LIR_OprFact::illegalOpr)
      , _tmp4(LIR_OprFact::illegalOpr)
      , _tmp5(LIR_OprFact::illegalOpr)
      , _condition(lir_cond_unknown) {
-     assert(code != lir_cmp && is_in_range(code, begin_op2, end_op2), "code check");
+     assert(code != lir_cmp && code != lir_branch && code != lir_cond_float_branch && is_in_range(code, begin_op2, end_op2), "code check");
    }
  
    LIR_Op2(LIR_Code code, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, LIR_Opr tmp1, LIR_Opr tmp2 = LIR_OprFact::illegalOpr,
            LIR_Opr tmp3 = LIR_OprFact::illegalOpr, LIR_Opr tmp4 = LIR_OprFact::illegalOpr, LIR_Opr tmp5 = LIR_OprFact::illegalOpr)
      : LIR_Op(code, result, NULL)

@@ -1667,11 +1632,11 @@
      , _tmp2(tmp2)
      , _tmp3(tmp3)
      , _tmp4(tmp4)
      , _tmp5(tmp5)
      , _condition(lir_cond_unknown) {
-     assert(code != lir_cmp && is_in_range(code, begin_op2, end_op2), "code check");
+     assert(code != lir_cmp && code != lir_branch && code != lir_cond_float_branch && is_in_range(code, begin_op2, end_op2), "code check");
    }
  
    LIR_Opr in_opr1() const                        { return _opr1; }
    LIR_Opr in_opr2() const                        { return _opr2; }
    BasicType type()  const                        { return _type; }

@@ -1679,14 +1644,14 @@
    LIR_Opr tmp2_opr() const                       { return _tmp2; }
    LIR_Opr tmp3_opr() const                       { return _tmp3; }
    LIR_Opr tmp4_opr() const                       { return _tmp4; }
    LIR_Opr tmp5_opr() const                       { return _tmp5; }
    LIR_Condition condition() const  {
-     assert(code() == lir_cmp || code() == lir_cmove || code() == lir_assert, "only valid for cmp and cmove and assert"); return _condition;
+     assert(code() == lir_cmp || code() == lir_branch || code() == lir_cond_float_branch || code() == lir_assert, "only valid for branch and assert"); return _condition;
    }
    void set_condition(LIR_Condition condition) {
-     assert(code() == lir_cmp || code() == lir_cmove, "only valid for cmp and cmove");  _condition = condition;
+     assert(code() == lir_cmp || code() == lir_branch || code() == lir_cond_float_branch, "only valid for branch"); _condition = condition;
    }
  
    void set_fpu_stack_size(int size)              { _fpu_stack_size = size; }
    int  fpu_stack_size() const                    { return _fpu_stack_size; }
  

@@ -1696,10 +1661,55 @@
    virtual void emit_code(LIR_Assembler* masm);
    virtual LIR_Op2* as_Op2() { return this; }
    virtual void print_instr(outputStream* out) const PRODUCT_RETURN;
  };
  
+ class LIR_OpBranch: public LIR_Op2 {
+  friend class LIR_OpVisitState;
+ 
+  private:
+   Label*        _label;
+   BlockBegin*   _block;  // if this is a branch to a block, this is the block
+   BlockBegin*   _ublock; // if this is a float-branch, this is the unorderd block
+   CodeStub*     _stub;   // if this is a branch to a stub, this is the stub
+ 
+  public:
+   LIR_OpBranch(LIR_Condition cond, Label* lbl)
+     : LIR_Op2(lir_branch, cond, LIR_OprFact::illegalOpr, LIR_OprFact::illegalOpr, (CodeEmitInfo*) NULL)
+     , _label(lbl)
+     , _block(NULL)
+     , _ublock(NULL)
+     , _stub(NULL) { }
+ 
+   LIR_OpBranch(LIR_Condition cond, BlockBegin* block);
+   LIR_OpBranch(LIR_Condition cond, CodeStub* stub);
+ 
+   // for unordered comparisons
+   LIR_OpBranch(LIR_Condition cond, BlockBegin* block, BlockBegin* ublock);
+ 
+   LIR_Condition cond() const {
+     return condition();
+   }
+ 
+   void set_cond(LIR_Condition cond) {
+     set_condition(cond);
+   }
+ 
+   Label*        label()       const              { return _label;       }
+   BlockBegin*   block()       const              { return _block;       }
+   BlockBegin*   ublock()      const              { return _ublock;      }
+   CodeStub*     stub()        const              { return _stub;        }
+ 
+   void          change_block(BlockBegin* b);
+   void          change_ublock(BlockBegin* b);
+   void          negate_cond();
+ 
+   virtual void emit_code(LIR_Assembler* masm);
+   virtual LIR_OpBranch* as_OpBranch() { return this; }
+   virtual void print_instr(outputStream* out) const PRODUCT_RETURN;
+ };
+ 
  class LIR_OpAllocArray : public LIR_Op {
   friend class LIR_OpVisitState;
  
   private:
    LIR_Opr   _klass;

@@ -1759,10 +1769,67 @@
    virtual void emit_code(LIR_Assembler* masm);
    virtual LIR_Op3* as_Op3() { return this; }
    virtual void print_instr(outputStream* out) const PRODUCT_RETURN;
  };
  
+ class LIR_Op4: public LIR_Op {
+   friend class LIR_OpVisitState;
+  protected:
+   LIR_Opr   _opr1;
+   LIR_Opr   _opr2;
+   LIR_Opr   _opr3;
+   LIR_Opr   _opr4;
+   BasicType _type;
+   LIR_Opr   _tmp1;
+   LIR_Opr   _tmp2;
+   LIR_Opr   _tmp3;
+   LIR_Opr   _tmp4;
+   LIR_Opr   _tmp5;
+   LIR_Condition _condition;
+ 
+  public:
+   LIR_Op4(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr opr3, LIR_Opr opr4,
+           LIR_Opr result, BasicType type)
+     : LIR_Op(code, result, NULL)
+     , _opr1(opr1)
+     , _opr2(opr2)
+     , _opr3(opr3)
+     , _opr4(opr4)
+     , _type(type)
+     , _tmp1(LIR_OprFact::illegalOpr)
+     , _tmp2(LIR_OprFact::illegalOpr)
+     , _tmp3(LIR_OprFact::illegalOpr)
+     , _tmp4(LIR_OprFact::illegalOpr)
+     , _tmp5(LIR_OprFact::illegalOpr)
+     , _condition(condition) {
+     assert(code == lir_cmove, "code check");
+     assert(type != T_ILLEGAL, "cmove should have type");
+   }
+ 
+   LIR_Opr in_opr1() const                        { return _opr1; }
+   LIR_Opr in_opr2() const                        { return _opr2; }
+   LIR_Opr in_opr3() const                        { return _opr3; }
+   LIR_Opr in_opr4() const                        { return _opr4; }
+   BasicType type()  const                        { return _type; }
+   LIR_Opr tmp1_opr() const                       { return _tmp1; }
+   LIR_Opr tmp2_opr() const                       { return _tmp2; }
+   LIR_Opr tmp3_opr() const                       { return _tmp3; }
+   LIR_Opr tmp4_opr() const                       { return _tmp4; }
+   LIR_Opr tmp5_opr() const                       { return _tmp5; }
+ 
+   LIR_Condition condition() const                { return _condition; }
+   void set_condition(LIR_Condition condition)    { _condition = condition; }
+ 
+   void set_in_opr1(LIR_Opr opr)                  { _opr1 = opr; }
+   void set_in_opr2(LIR_Opr opr)                  { _opr2 = opr; }
+   void set_in_opr3(LIR_Opr opr)                  { _opr3 = opr; }
+   void set_in_opr4(LIR_Opr opr)                  { _opr4 = opr; }
+   virtual void emit_code(LIR_Assembler* masm);
+   virtual LIR_Op4* as_Op4() { return this; }
+ 
+   virtual void print_instr(outputStream* out) const PRODUCT_RETURN;
+ };
  
  //--------------------------------
  class LabelObj: public CompilationResourceObj {
   private:
    Label _label;

@@ -1981,10 +2048,14 @@
  #endif
  #ifdef ASSERT
    const char *  _file;
    int           _line;
  #endif
+ #ifdef RISCV
+   LIR_Opr       _cmp_opr1;
+   LIR_Opr       _cmp_opr2;
+ #endif
  
   public:
    void append(LIR_Op* op) {
      if (op->source() == NULL)
        op->set_source(_compilation->current_instruction());

@@ -1993,10 +2064,25 @@
        _compilation->maybe_print_current_instruction();
        op->print(); tty->cr();
      }
  #endif // PRODUCT
  
+ #ifdef RISCV
+     if (op->code() == lir_branch || op->code() == 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);
+       }
+     } else if (op->code() == lir_cmove) {
+       op->as_Op4()->set_in_opr3(_cmp_opr1);
+       op->as_Op4()->set_in_opr4(_cmp_opr2);
+     }
+ #endif
+ 
      _operations.append(op);
  
  #ifdef ASSERT
      op->verify();
      op->set_file_and_line(_file, _line);

@@ -2009,10 +2095,17 @@
  
  #ifdef ASSERT
    void set_file_and_line(const char * file, int line);
  #endif
  
+ #ifdef RISCV
+   void set_cmp_oprs(LIR_Opr opr1, LIR_Opr opr2) {
+     _cmp_opr1 = opr1;
+     _cmp_opr2 = opr2;
+   }
+ #endif
+ 
    //---------- accessors ---------------
    LIR_OpList* instructions_list()                { return &_operations; }
    int         length() const                     { return _operations.length(); }
    LIR_Op*     at(int i) const                    { return _operations.at(i); }
  

@@ -2116,21 +2209,26 @@
  
    void push(LIR_Opr opr)                                   { append(new LIR_Op1(lir_push, opr)); }
    void pop(LIR_Opr reg)                                    { append(new LIR_Op1(lir_pop,  reg)); }
  
    void cmp(LIR_Condition condition, LIR_Opr left, LIR_Opr right, CodeEmitInfo* info = NULL) {
+ #ifdef RISCV
+     set_cmp_oprs(left, right);
+ #else
      append(new LIR_Op2(lir_cmp, condition, left, right, info));
+ #endif
    }
    void cmp(LIR_Condition condition, LIR_Opr left, int right, CodeEmitInfo* info = NULL) {
      cmp(condition, left, LIR_OprFact::intConst(right), info);
    }
  
    void cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info);
    void cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Address* addr, CodeEmitInfo* info);
  
-   void cmove(LIR_Condition condition, LIR_Opr src1, LIR_Opr src2, LIR_Opr dst, BasicType type) {
-     append(new LIR_Op2(lir_cmove, condition, src1, src2, dst, type));
+   void cmove(LIR_Condition condition, LIR_Opr src1, LIR_Opr src2, LIR_Opr dst, BasicType type,
+              LIR_Opr cmp_opr1 = LIR_OprFact::illegalOpr, LIR_Opr cmp_opr2 = LIR_OprFact::illegalOpr) {
+     append(new LIR_Op4(lir_cmove, condition, src1, src2, cmp_opr1, cmp_opr2, dst, type));
    }
  
    void cas_long(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value,
                  LIR_Opr t1, LIR_Opr t2, LIR_Opr result = LIR_OprFact::illegalOpr);
    void cas_obj(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value,
< prev index next >