hotspot/src/cpu/x86/vm/x86_32.ad
changeset 7121 69928525c55c
parent 7115 32300e243300
child 7433 b418028612ad
equal deleted inserted replaced
7120:2d1dbf14fe62 7121:69928525c55c
  8861 instruct divL_eReg_imm32( eADXRegL dst, immL32 imm, eRegI tmp, eRegI tmp2, eFlagsReg cr ) %{
  8861 instruct divL_eReg_imm32( eADXRegL dst, immL32 imm, eRegI tmp, eRegI tmp2, eFlagsReg cr ) %{
  8862   match(Set dst (DivL dst imm));
  8862   match(Set dst (DivL dst imm));
  8863   effect( TEMP tmp, TEMP tmp2, KILL cr );
  8863   effect( TEMP tmp, TEMP tmp2, KILL cr );
  8864   ins_cost(1000);
  8864   ins_cost(1000);
  8865   format %{ "MOV    $tmp,abs($imm) # ldiv EDX:EAX,$imm\n\t"
  8865   format %{ "MOV    $tmp,abs($imm) # ldiv EDX:EAX,$imm\n\t"
       
  8866             "XOR    $tmp2,$tmp2\n\t"
  8866             "CMP    $tmp,EDX\n\t"
  8867             "CMP    $tmp,EDX\n\t"
  8867             "JA,s   fast\n\t"
  8868             "JA,s   fast\n\t"
  8868             "MOV    $tmp2,EAX\n\t"
  8869             "MOV    $tmp2,EAX\n\t"
  8869             "MOV    EAX,EDX\n\t"
  8870             "MOV    EAX,EDX\n\t"
  8870             "SAR    EDX,31\n\t"
  8871             "MOV    EDX,0\n\t"
  8871             "IDIV   $tmp\n\t"
  8872             "JLE,s  pos\n\t"
  8872             "XCHG   EAX,$tmp2 \n\t"
  8873             "LNEG   EAX : $tmp2\n\t"
  8873             "IDIV   $tmp\n\t"
  8874             "DIV    $tmp # unsigned division\n\t"
  8874             "CDQ\n\t"
  8875             "XCHG   EAX,$tmp2\n\t"
  8875             "ADD    EDX,$tmp2\n\t"
  8876             "DIV    $tmp\n\t"
       
  8877             "LNEG   $tmp2 : EAX\n\t"
  8876             "JMP,s  done\n"
  8878             "JMP,s  done\n"
       
  8879     "pos:\n\t"
       
  8880             "DIV    $tmp\n\t"
       
  8881             "XCHG   EAX,$tmp2\n"
  8877     "fast:\n\t"
  8882     "fast:\n\t"
  8878             "IDIV   $tmp\n\t"
  8883             "DIV    $tmp\n"
  8879             "XOR    EDX,EDX\n"
       
  8880     "done:\n\t"
  8884     "done:\n\t"
       
  8885             "MOV    EDX,$tmp2\n\t"
  8881             "NEG    EDX:EAX # if $imm < 0" %}
  8886             "NEG    EDX:EAX # if $imm < 0" %}
  8882   ins_encode %{
  8887   ins_encode %{
  8883     int con = (int)$imm$$constant;
  8888     int con = (int)$imm$$constant;
  8884     assert(con != 0 && con != -1 && con != min_jint, "wrong divisor");
  8889     assert(con != 0 && con != -1 && con != min_jint, "wrong divisor");
  8885     int pcon = (con > 0) ? con : -con;
  8890     int pcon = (con > 0) ? con : -con;
  8886     Label Lfast, Ldone;
  8891     Label Lfast, Lpos, Ldone;
  8887 
  8892 
  8888     __ movl($tmp$$Register, pcon);
  8893     __ movl($tmp$$Register, pcon);
       
  8894     __ xorl($tmp2$$Register,$tmp2$$Register);
  8889     __ cmpl($tmp$$Register, HIGH_FROM_LOW($dst$$Register));
  8895     __ cmpl($tmp$$Register, HIGH_FROM_LOW($dst$$Register));
  8890     __ jccb(Assembler::above, Lfast);
  8896     __ jccb(Assembler::above, Lfast); // result fits into 32 bit
  8891 
  8897 
  8892     __ movl($tmp2$$Register, $dst$$Register); // save
  8898     __ movl($tmp2$$Register, $dst$$Register); // save
  8893     __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register));
  8899     __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register));
  8894     __ sarl(HIGH_FROM_LOW($dst$$Register), 31); // src sign
  8900     __ movl(HIGH_FROM_LOW($dst$$Register),0); // preserve flags
  8895     __ idivl($tmp$$Register);
  8901     __ jccb(Assembler::lessEqual, Lpos); // result is positive
       
  8902 
       
  8903     // Negative dividend.
       
  8904     // convert value to positive to use unsigned division
       
  8905     __ lneg($dst$$Register, $tmp2$$Register);
       
  8906     __ divl($tmp$$Register);
  8896     __ xchgl($dst$$Register, $tmp2$$Register);
  8907     __ xchgl($dst$$Register, $tmp2$$Register);
  8897     __ idivl($tmp$$Register);
  8908     __ divl($tmp$$Register);
  8898     __ cdql();
  8909     // revert result back to negative
  8899     __ addl(HIGH_FROM_LOW($dst$$Register),$tmp2$$Register);
  8910     __ lneg($tmp2$$Register, $dst$$Register);
  8900     __ jmpb(Ldone);
  8911     __ jmpb(Ldone);
  8901 
  8912 
       
  8913     __ bind(Lpos);
       
  8914     __ divl($tmp$$Register); // Use unsigned division
       
  8915     __ xchgl($dst$$Register, $tmp2$$Register);
       
  8916     // Fallthrow for final divide, tmp2 has 32 bit hi result
       
  8917 
  8902     __ bind(Lfast);
  8918     __ bind(Lfast);
  8903     // fast path: src is positive and result fits into 32 bit
  8919     // fast path: src is positive
  8904     __ idivl($tmp$$Register);
  8920     __ divl($tmp$$Register); // Use unsigned division
  8905     __ xorl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
       
  8906 
  8921 
  8907     __ bind(Ldone);
  8922     __ bind(Ldone);
       
  8923     __ movl(HIGH_FROM_LOW($dst$$Register),$tmp2$$Register);
  8908     if (con < 0) {
  8924     if (con < 0) {
  8909       __ lneg(HIGH_FROM_LOW($dst$$Register), $dst$$Register);
  8925       __ lneg(HIGH_FROM_LOW($dst$$Register), $dst$$Register);
  8910     }
  8926     }
  8911   %}
  8927   %}
  8912   ins_pipe( pipe_slow );
  8928   ins_pipe( pipe_slow );
  8920   format %{ "MOV    $tmp,abs($imm) # lrem EDX:EAX,$imm\n\t"
  8936   format %{ "MOV    $tmp,abs($imm) # lrem EDX:EAX,$imm\n\t"
  8921             "CMP    $tmp,EDX\n\t"
  8937             "CMP    $tmp,EDX\n\t"
  8922             "JA,s   fast\n\t"
  8938             "JA,s   fast\n\t"
  8923             "MOV    $tmp2,EAX\n\t"
  8939             "MOV    $tmp2,EAX\n\t"
  8924             "MOV    EAX,EDX\n\t"
  8940             "MOV    EAX,EDX\n\t"
  8925             "SAR    EDX,31\n\t"
  8941             "MOV    EDX,0\n\t"
  8926             "IDIV   $tmp\n\t"
  8942             "JLE,s  pos\n\t"
       
  8943             "LNEG   EAX : $tmp2\n\t"
       
  8944             "DIV    $tmp # unsigned division\n\t"
       
  8945             "MOV    EAX,$tmp2\n\t"
       
  8946             "DIV    $tmp\n\t"
       
  8947             "NEG    EDX\n\t"
       
  8948             "JMP,s  done\n"
       
  8949     "pos:\n\t"
       
  8950             "DIV    $tmp\n\t"
  8927             "MOV    EAX,$tmp2\n"
  8951             "MOV    EAX,$tmp2\n"
  8928     "fast:\n\t"
  8952     "fast:\n\t"
  8929             "IDIV   $tmp\n\t"
  8953             "DIV    $tmp\n"
       
  8954     "done:\n\t"
  8930             "MOV    EAX,EDX\n\t"
  8955             "MOV    EAX,EDX\n\t"
  8931             "SAR    EDX,31\n\t" %}
  8956             "SAR    EDX,31\n\t" %}
  8932   ins_encode %{
  8957   ins_encode %{
  8933     int con = (int)$imm$$constant;
  8958     int con = (int)$imm$$constant;
  8934     assert(con != 0 && con != -1 && con != min_jint, "wrong divisor");
  8959     assert(con != 0 && con != -1 && con != min_jint, "wrong divisor");
  8935     int pcon = (con > 0) ? con : -con;
  8960     int pcon = (con > 0) ? con : -con;
  8936     Label  Lfast;
  8961     Label  Lfast, Lpos, Ldone;
  8937 
  8962 
  8938     __ movl($tmp$$Register, pcon);
  8963     __ movl($tmp$$Register, pcon);
  8939     __ cmpl($tmp$$Register, HIGH_FROM_LOW($dst$$Register));
  8964     __ cmpl($tmp$$Register, HIGH_FROM_LOW($dst$$Register));
  8940     __ jccb(Assembler::above, Lfast); // src is positive and result fits into 32 bit
  8965     __ jccb(Assembler::above, Lfast); // src is positive and result fits into 32 bit
  8941 
  8966 
  8942     __ movl($tmp2$$Register, $dst$$Register); // save
  8967     __ movl($tmp2$$Register, $dst$$Register); // save
  8943     __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register));
  8968     __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register));
  8944     __ sarl(HIGH_FROM_LOW($dst$$Register), 31); // src sign
  8969     __ movl(HIGH_FROM_LOW($dst$$Register),0); // preserve flags
  8945     __ idivl($tmp$$Register);
  8970     __ jccb(Assembler::lessEqual, Lpos); // result is positive
       
  8971 
       
  8972     // Negative dividend.
       
  8973     // convert value to positive to use unsigned division
       
  8974     __ lneg($dst$$Register, $tmp2$$Register);
       
  8975     __ divl($tmp$$Register);
  8946     __ movl($dst$$Register, $tmp2$$Register);
  8976     __ movl($dst$$Register, $tmp2$$Register);
       
  8977     __ divl($tmp$$Register);
       
  8978     // revert remainder back to negative
       
  8979     __ negl(HIGH_FROM_LOW($dst$$Register));
       
  8980     __ jmpb(Ldone);
       
  8981 
       
  8982     __ bind(Lpos);
       
  8983     __ divl($tmp$$Register);
       
  8984     __ movl($dst$$Register, $tmp2$$Register);
  8947 
  8985 
  8948     __ bind(Lfast);
  8986     __ bind(Lfast);
  8949     __ idivl($tmp$$Register);
  8987     // fast path: src is positive
       
  8988     __ divl($tmp$$Register);
       
  8989 
       
  8990     __ bind(Ldone);
  8950     __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register));
  8991     __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register));
  8951     __ sarl(HIGH_FROM_LOW($dst$$Register), 31); // result sign
  8992     __ sarl(HIGH_FROM_LOW($dst$$Register), 31); // result sign
  8952 
  8993 
  8953   %}
  8994   %}
  8954   ins_pipe( pipe_slow );
  8995   ins_pipe( pipe_slow );