hotspot/src/cpu/x86/vm/assembler_x86.cpp
int MacroAssembler::corrected_idivl(Register reg) {
{- -------------------------------------------
(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.