src/cpu/x86/vm/x86_32.ad

changeset 4944
886d1fd67dc3
parent 4873
e961c11b85fe
child 5001
e10e43e58e92
     1.1 --- a/src/cpu/x86/vm/x86_32.ad	Fri Apr 12 20:37:18 2013 -0400
     1.2 +++ b/src/cpu/x86/vm/x86_32.ad	Fri Apr 12 19:14:47 2013 -0700
     1.3 @@ -1,5 +1,5 @@
     1.4  //
     1.5 -// Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     1.6 +// Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     1.7  // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8  //
     1.9  // This code is free software; you can redistribute it and/or modify it
    1.10 @@ -2317,30 +2317,6 @@
    1.11      emit_rm(cbuf, 0x3, $p$$reg, tmpReg);
    1.12    %}
    1.13  
    1.14 -  enc_class enc_cmpLTP_mem(rRegI p, rRegI q, memory mem, eCXRegI tmp) %{    // cadd_cmpLT
    1.15 -    int tmpReg = $tmp$$reg;
    1.16 -
    1.17 -    // SUB $p,$q
    1.18 -    emit_opcode(cbuf,0x2B);
    1.19 -    emit_rm(cbuf, 0x3, $p$$reg, $q$$reg);
    1.20 -    // SBB $tmp,$tmp
    1.21 -    emit_opcode(cbuf,0x1B);
    1.22 -    emit_rm(cbuf, 0x3, tmpReg, tmpReg);
    1.23 -    // AND $tmp,$y
    1.24 -    cbuf.set_insts_mark();       // Mark start of opcode for reloc info in mem operand
    1.25 -    emit_opcode(cbuf,0x23);
    1.26 -    int reg_encoding = tmpReg;
    1.27 -    int base  = $mem$$base;
    1.28 -    int index = $mem$$index;
    1.29 -    int scale = $mem$$scale;
    1.30 -    int displace = $mem$$disp;
    1.31 -    relocInfo::relocType disp_reloc = $mem->disp_reloc();
    1.32 -    encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_reloc);
    1.33 -    // ADD $p,$tmp
    1.34 -    emit_opcode(cbuf,0x03);
    1.35 -    emit_rm(cbuf, 0x3, $p$$reg, tmpReg);
    1.36 -  %}
    1.37 -
    1.38    enc_class shift_left_long( eRegL dst, eCXRegI shift ) %{
    1.39      // TEST shift,32
    1.40      emit_opcode(cbuf,0xF7);
    1.41 @@ -8922,9 +8898,9 @@
    1.42    %}
    1.43  %}
    1.44  
    1.45 -instruct cmpLTMask( eCXRegI dst, ncxRegI p, ncxRegI q, eFlagsReg cr ) %{
    1.46 +instruct cmpLTMask(eCXRegI dst, ncxRegI p, ncxRegI q, eFlagsReg cr) %{
    1.47    match(Set dst (CmpLTMask p q));
    1.48 -  effect( KILL cr );
    1.49 +  effect(KILL cr);
    1.50    ins_cost(400);
    1.51  
    1.52    // SETlt can only use low byte of EAX,EBX, ECX, or EDX as destination
    1.53 @@ -8932,50 +8908,83 @@
    1.54              "CMP    $p,$q\n\t"
    1.55              "SETlt  $dst\n\t"
    1.56              "NEG    $dst" %}
    1.57 -  ins_encode( OpcRegReg(0x33,dst,dst),
    1.58 -              OpcRegReg(0x3B,p,q),
    1.59 -              setLT_reg(dst), neg_reg(dst) );
    1.60 -  ins_pipe( pipe_slow );
    1.61 -%}
    1.62 -
    1.63 -instruct cmpLTMask0( rRegI dst, immI0 zero, eFlagsReg cr ) %{
    1.64 +  ins_encode %{
    1.65 +    Register Rp = $p$$Register;
    1.66 +    Register Rq = $q$$Register;
    1.67 +    Register Rd = $dst$$Register;
    1.68 +    Label done;
    1.69 +    __ xorl(Rd, Rd);
    1.70 +    __ cmpl(Rp, Rq);
    1.71 +    __ setb(Assembler::less, Rd);
    1.72 +    __ negl(Rd);
    1.73 +  %}
    1.74 +
    1.75 +  ins_pipe(pipe_slow);
    1.76 +%}
    1.77 +
    1.78 +instruct cmpLTMask0(rRegI dst, immI0 zero, eFlagsReg cr) %{
    1.79    match(Set dst (CmpLTMask dst zero));
    1.80 -  effect( DEF dst, KILL cr );
    1.81 +  effect(DEF dst, KILL cr);
    1.82    ins_cost(100);
    1.83  
    1.84 -  format %{ "SAR    $dst,31" %}
    1.85 -  opcode(0xC1, 0x7);  /* C1 /7 ib */
    1.86 -  ins_encode( RegOpcImm( dst, 0x1F ) );
    1.87 -  ins_pipe( ialu_reg );
    1.88 -%}
    1.89 -
    1.90 -
    1.91 -instruct cadd_cmpLTMask( ncxRegI p, ncxRegI q, ncxRegI y, eCXRegI tmp, eFlagsReg cr ) %{
    1.92 +  format %{ "SAR    $dst,31\t# cmpLTMask0" %}
    1.93 +  ins_encode %{
    1.94 +  __ sarl($dst$$Register, 31);
    1.95 +  %}
    1.96 +  ins_pipe(ialu_reg);
    1.97 +%}
    1.98 +
    1.99 +/* better to save a register than avoid a branch */
   1.100 +instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, eFlagsReg cr) %{
   1.101    match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
   1.102 -  effect( KILL tmp, KILL cr );
   1.103 +  effect(KILL cr);
   1.104    ins_cost(400);
   1.105 -  // annoyingly, $tmp has no edges so you cant ask for it in
   1.106 -  // any format or encoding
   1.107 -  format %{ "SUB    $p,$q\n\t"
   1.108 -            "SBB    ECX,ECX\n\t"
   1.109 -            "AND    ECX,$y\n\t"
   1.110 -            "ADD    $p,ECX" %}
   1.111 -  ins_encode( enc_cmpLTP(p,q,y,tmp) );
   1.112 -  ins_pipe( pipe_cmplt );
   1.113 +  format %{ "SUB    $p,$q\t# cadd_cmpLTMask\n\t"
   1.114 +            "JGE    done\n\t"
   1.115 +            "ADD    $p,$y\n"
   1.116 +            "done:  " %}
   1.117 +  ins_encode %{
   1.118 +    Register Rp = $p$$Register;
   1.119 +    Register Rq = $q$$Register;
   1.120 +    Register Ry = $y$$Register;
   1.121 +    Label done;
   1.122 +    __ subl(Rp, Rq);
   1.123 +    __ jccb(Assembler::greaterEqual, done);
   1.124 +    __ addl(Rp, Ry);
   1.125 +    __ bind(done);
   1.126 +  %}
   1.127 +
   1.128 +  ins_pipe(pipe_cmplt);
   1.129 +%}
   1.130 +
   1.131 +/* better to save a register than avoid a branch */
   1.132 +instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, eFlagsReg cr) %{
   1.133 +  match(Set y (AndI (CmpLTMask p q) y));
   1.134 +  effect(KILL cr);
   1.135 +
   1.136 +  ins_cost(300);
   1.137 +
   1.138 +  format %{ "CMPL     $p, $q\t# and_cmpLTMask\n\t"
   1.139 +            "JLT      done\n\t"
   1.140 +            "XORL     $y, $y\n"
   1.141 +            "done:  " %}
   1.142 +  ins_encode %{
   1.143 +    Register Rp = $p$$Register;
   1.144 +    Register Rq = $q$$Register;
   1.145 +    Register Ry = $y$$Register;
   1.146 +    Label done;
   1.147 +    __ cmpl(Rp, Rq);
   1.148 +    __ jccb(Assembler::less, done);
   1.149 +    __ xorl(Ry, Ry);
   1.150 +    __ bind(done);
   1.151 +  %}
   1.152 +
   1.153 +  ins_pipe(pipe_cmplt);
   1.154  %}
   1.155  
   1.156  /* If I enable this, I encourage spilling in the inner loop of compress.
   1.157 -instruct cadd_cmpLTMask_mem( ncxRegI p, ncxRegI q, memory y, eCXRegI tmp, eFlagsReg cr ) %{
   1.158 +instruct cadd_cmpLTMask_mem(ncxRegI p, ncxRegI q, memory y, eCXRegI tmp, eFlagsReg cr) %{
   1.159    match(Set p (AddI (AndI (CmpLTMask p q) (LoadI y)) (SubI p q)));
   1.160 -  effect( USE_KILL tmp, KILL cr );
   1.161 -  ins_cost(400);
   1.162 -
   1.163 -  format %{ "SUB    $p,$q\n\t"
   1.164 -            "SBB    ECX,ECX\n\t"
   1.165 -            "AND    ECX,$y\n\t"
   1.166 -            "ADD    $p,ECX" %}
   1.167 -  ins_encode( enc_cmpLTP_mem(p,q,y,tmp) );
   1.168 -%}
   1.169  */
   1.170  
   1.171  //----------Long Instructions------------------------------------------------

mercurial