Top


定義場所(file name)

hotspot/src/cpu/x86/vm/assembler_x86.cpp

名前(function name)

int MacroAssembler::corrected_idivl(Register reg) {

本体部(body)

  {- -------------------------------------------
  (1) (JVM の除算/剰余算は, 境界値での挙動が x86 とは異なるため, チェックが必要)
      ---------------------------------------- -}

      // Full implementation of Java idiv and irem; checks for
      // special case as described in JVM spec., p.243 & p.271.
      // The function returns the (pc) offset of the idivl
      // instruction - may be needed for implicit exceptions.
      //
      //         normal case                           special case
      //
      // input : rax,: dividend                         min_int
      //         reg: divisor   (may not be rax,/rdx)   -1
      //
      // output: rax,: quotient  (= rax, idiv reg)       min_int
      //         rdx: remainder (= rax, irem reg)       0

  {- -------------------------------------------
  (1) (assert)
      ---------------------------------------- -}

      assert(reg != rax && reg != rdx, "reg cannot be rax, or rdx register");

  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}

      const int min_int = 0x80000000;
      Label normal_case, special_case;

  {- -------------------------------------------
  (1) コード生成:
      「special case かどうかのチェックを行う.
        結果に応じて, 以下の処理は2通りに分岐.」
      ---------------------------------------- -}

      // check for special case
      cmpl(rax, min_int);
      jcc(Assembler::notEqual, normal_case);

  {- -------------------------------------------
  (1) コード生成:
      「special case 用の処理を行う.」
      ---------------------------------------- -}

      xorl(rdx, rdx); // prepare rdx for possible special case (where remainder = 0)
      cmpl(reg, -1);
      jcc(Assembler::equal, special_case);

  {- -------------------------------------------
  (1) コード生成:
      「normal case 用の処理を行う.」
      ---------------------------------------- -}

      // handle normal case
      bind(normal_case);
      cdql();
      int idivl_offset = offset();
      idivl(reg);

  {- -------------------------------------------
  (1) コード生成:
      「(special case/normal case どちらもここで合流)」
      ---------------------------------------- -}

      // normal and special case exit
      bind(special_case);

  {- -------------------------------------------
  (1) リターン
      ---------------------------------------- -}

      return idivl_offset;
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.