Print this page
rev 1838 : 6961690: load oops from constant table on SPARC
Summary: oops should be loaded from the constant table of an nmethod instead of materializing them with a long code sequence.
Reviewed-by:

Split Close
Expand all
Collapse all
          --- old/src/cpu/x86/vm/x86_32.ad
          +++ new/src/cpu/x86/vm/x86_32.ad
↓ open down ↓ 499 lines elided ↑ open up ↑
 500  500      // reg-reg copy, use an empty encoding
 501  501    } else {
 502  502      MacroAssembler _masm(&cbuf);
 503  503  
 504  504      __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding));
 505  505    }
 506  506  }
 507  507  
 508  508  
 509  509  //=============================================================================
      510 +const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
      511 +
      512 +void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
      513 +  emit_constant_table(cbuf);
      514 +  set_table_base_offset(0);
      515 +  // Empty encoding
      516 +}
      517 +
      518 +uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
      519 +  // Compute the size (even if it's zero) since
      520 +  // Compile::Shorten_branches needs the table to be emitted (which
      521 +  // happens in Compile::scratch_emit_size) to calculate the size for
      522 +  // MachConstantNode's.
      523 +  return MachNode::size(ra_);
      524 +}
      525 +
      526 +#ifndef PRODUCT
      527 +void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
      528 +  st->print("# MachConstantBaseNode (empty encoding)");
      529 +}
      530 +#endif
      531 +
      532 +
      533 +//=============================================================================
 510  534  #ifndef PRODUCT
 511  535  void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
 512  536    Compile* C = ra_->C;
 513  537    if( C->in_24_bit_fp_mode() ) {
 514  538      st->print("FLDCW  24 bit fpu control word");
 515  539      st->print_cr(""); st->print("\t");
 516  540    }
 517  541  
 518  542    int framesize = C->frame_slots() << LogBytesPerInt;
 519  543    assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
↓ open down ↓ 793 lines elided ↑ open up ↑
1313 1337    InternalAddress here(__ pc());
1314 1338    __ pushptr(here.addr());
1315 1339  
1316 1340    __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
1317 1341    assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1318 1342    __ end_a_stub();
1319 1343    return offset;
1320 1344  }
1321 1345  
1322 1346  
1323      -static void emit_double_constant(CodeBuffer& cbuf, double x) {
1324      -  int mark = cbuf.insts()->mark_off();
1325      -  MacroAssembler _masm(&cbuf);
1326      -  address double_address = __ double_constant(x);
1327      -  cbuf.insts()->set_mark_off(mark);  // preserve mark across masm shift
1328      -  emit_d32_reloc(cbuf,
1329      -                 (int)double_address,
1330      -                 internal_word_Relocation::spec(double_address),
1331      -                 RELOC_DISP32);
1332      -}
1333      -
1334      -static void emit_float_constant(CodeBuffer& cbuf, float x) {
1335      -  int mark = cbuf.insts()->mark_off();
1336      -  MacroAssembler _masm(&cbuf);
1337      -  address float_address = __ float_constant(x);
1338      -  cbuf.insts()->set_mark_off(mark);  // preserve mark across masm shift
1339      -  emit_d32_reloc(cbuf,
1340      -                 (int)float_address,
1341      -                 internal_word_Relocation::spec(float_address),
1342      -                 RELOC_DISP32);
1343      -}
1344      -
1345      -
1346 1347  const bool Matcher::match_rule_supported(int opcode) {
1347 1348    if (!has_match_rule(opcode))
1348 1349      return false;
1349 1350  
1350 1351    return true;  // Per default match rules are supported.
1351 1352  }
1352 1353  
1353 1354  int Matcher::regnum_to_fpu_offset(int regnum) {
1354 1355    return regnum - 32; // The FP registers are in the second chunk
1355 1356  }
1356 1357  
1357      -bool is_positive_zero_float(jfloat f) {
1358      -  return jint_cast(f) == jint_cast(0.0F);
1359      -}
1360      -
1361      -bool is_positive_one_float(jfloat f) {
1362      -  return jint_cast(f) == jint_cast(1.0F);
1363      -}
1364      -
1365      -bool is_positive_zero_double(jdouble d) {
1366      -  return jlong_cast(d) == jlong_cast(0.0);
1367      -}
1368      -
1369      -bool is_positive_one_double(jdouble d) {
1370      -  return jlong_cast(d) == jlong_cast(1.0);
1371      -}
1372      -
1373 1358  // This is UltraSparc specific, true just means we have fast l2f conversion
1374 1359  const bool Matcher::convL2FSupported(void) {
1375 1360    return true;
1376 1361  }
1377 1362  
1378 1363  // Vector width in bytes
1379 1364  const uint Matcher::vector_width_in_bytes(void) {
1380 1365    return UseSSE >= 2 ? 8 : 0;
1381 1366  }
1382 1367  
↓ open down ↓ 646 lines elided ↑ open up ↑
2029 2014        // xor dst, dst
2030 2015        emit_opcode(cbuf, 0x33);
2031 2016        emit_rm(cbuf, 0x3, dst_enc, dst_enc);
2032 2017      } else {
2033 2018        emit_opcode(cbuf, $primary + dst_enc);
2034 2019        emit_d32(cbuf, src_con);
2035 2020      }
2036 2021    %}
2037 2022  
2038 2023  
2039      -  enc_class LdImmD (immD src) %{    // Load Immediate
2040      -    if( is_positive_zero_double($src$$constant)) {
2041      -      // FLDZ
2042      -      emit_opcode(cbuf,0xD9);
2043      -      emit_opcode(cbuf,0xEE);
2044      -    } else if( is_positive_one_double($src$$constant)) {
2045      -      // FLD1
2046      -      emit_opcode(cbuf,0xD9);
2047      -      emit_opcode(cbuf,0xE8);
2048      -    } else {
2049      -      emit_opcode(cbuf,0xDD);
2050      -      emit_rm(cbuf, 0x0, 0x0, 0x5);
2051      -      emit_double_constant(cbuf, $src$$constant);
2052      -    }
2053      -  %}
2054      -
2055      -
2056      -  enc_class LdImmF (immF src) %{    // Load Immediate
2057      -    if( is_positive_zero_float($src$$constant)) {
2058      -      emit_opcode(cbuf,0xD9);
2059      -      emit_opcode(cbuf,0xEE);
2060      -    } else if( is_positive_one_float($src$$constant)) {
2061      -      emit_opcode(cbuf,0xD9);
2062      -      emit_opcode(cbuf,0xE8);
2063      -    } else {
2064      -      $$$emit8$primary;
2065      -      // Load immediate does not have a zero or sign extended version
2066      -      // for 8-bit immediates
2067      -      // First load to TOS, then move to dst
2068      -      emit_rm(cbuf, 0x0, 0x0, 0x5);
2069      -      emit_float_constant(cbuf, $src$$constant);
2070      -    }
2071      -  %}
2072      -
2073      -  enc_class LdImmX (regX dst, immXF con) %{    // Load Immediate
2074      -    emit_rm(cbuf, 0x0, $dst$$reg, 0x5);
2075      -    emit_float_constant(cbuf, $con$$constant);
2076      -  %}
2077      -
2078      -  enc_class LdImmXD (regXD dst, immXD con) %{    // Load Immediate
2079      -    emit_rm(cbuf, 0x0, $dst$$reg, 0x5);
2080      -    emit_double_constant(cbuf, $con$$constant);
2081      -  %}
2082      -
2083      -  enc_class load_conXD (regXD dst, immXD con) %{ // Load double constant
2084      -    // UseXmmLoadAndClearUpper ? movsd(dst, con) : movlpd(dst, con)
2085      -    emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66);
2086      -    emit_opcode(cbuf, 0x0F);
2087      -    emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12);
2088      -    emit_rm(cbuf, 0x0, $dst$$reg, 0x5);
2089      -    emit_double_constant(cbuf, $con$$constant);
2090      -  %}
2091      -
2092      -  enc_class Opc_MemImm_F(immF src) %{
2093      -    cbuf.set_insts_mark();
2094      -    $$$emit8$primary;
2095      -    emit_rm(cbuf, 0x0, $secondary, 0x5);
2096      -    emit_float_constant(cbuf, $src$$constant);
2097      -  %}
2098      -
2099      -
2100 2024    enc_class MovI2X_reg(regX dst, eRegI src) %{
2101 2025      emit_opcode(cbuf, 0x66 );     // MOVD dst,src
2102 2026      emit_opcode(cbuf, 0x0F );
2103 2027      emit_opcode(cbuf, 0x6E );
2104 2028      emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
2105 2029    %}
2106 2030  
2107 2031    enc_class MovX2I_reg(eRegI dst, regX src) %{
2108 2032      emit_opcode(cbuf, 0x66 );     // MOVD dst,src
2109 2033      emit_opcode(cbuf, 0x0F );
↓ open down ↓ 2684 lines elided ↑ open up ↑
4794 4718    // Do additional (and counter-intuitive) test against NaN to work around VC++
4795 4719    // bug that generates code such that NaNs compare equal to 0.0
4796 4720    predicate( UseSSE<=1 && n->getd() == 0.0 && !g_isnan(n->getd()) );
4797 4721    match(ConD);
4798 4722  
4799 4723    op_cost(5);
4800 4724    format %{ %}
4801 4725    interface(CONST_INTER);
4802 4726  %}
4803 4727  
4804      -// Double Immediate
     4728 +// Double Immediate one
4805 4729  operand immD1() %{
4806 4730    predicate( UseSSE<=1 && n->getd() == 1.0 );
4807 4731    match(ConD);
4808 4732  
4809 4733    op_cost(5);
4810 4734    format %{ %}
4811 4735    interface(CONST_INTER);
4812 4736  %}
4813 4737  
4814 4738  // Double Immediate
↓ open down ↓ 22 lines elided ↑ open up ↑
4837 4761    // compare equal to -0.0.
4838 4762    predicate( UseSSE>=2 && jlong_cast(n->getd()) == 0 );
4839 4763    match(ConD);
4840 4764  
4841 4765    format %{ %}
4842 4766    interface(CONST_INTER);
4843 4767  %}
4844 4768  
4845 4769  // Float Immediate zero
4846 4770  operand immF0() %{
4847      -  predicate( UseSSE == 0 && n->getf() == 0.0 );
     4771 +  predicate(UseSSE == 0 && n->getf() == 0.0F);
     4772 +  match(ConF);
     4773 +
     4774 +  op_cost(5);
     4775 +  format %{ %}
     4776 +  interface(CONST_INTER);
     4777 +%}
     4778 +
     4779 +// Float Immediate one
     4780 +operand immF1() %{
     4781 +  predicate(UseSSE == 0 && n->getf() == 1.0F);
4848 4782    match(ConF);
4849 4783  
4850 4784    op_cost(5);
4851 4785    format %{ %}
4852 4786    interface(CONST_INTER);
4853 4787  %}
4854 4788  
4855 4789  // Float Immediate
4856 4790  operand immF() %{
4857 4791    predicate( UseSSE == 0 );
↓ open down ↓ 2350 lines elided ↑ open up ↑
7208 7142    effect(KILL cr);
7209 7143    ins_cost(150);
7210 7144    format %{ "XOR    $dst.lo,$dst.lo\n\t"
7211 7145              "XOR    $dst.hi,$dst.hi" %}
7212 7146    opcode(0x33,0x33);
7213 7147    ins_encode( RegReg_Lo(dst,dst), RegReg_Hi(dst, dst) );
7214 7148    ins_pipe( ialu_reg_long );
7215 7149  %}
7216 7150  
7217 7151  // The instruction usage is guarded by predicate in operand immF().
7218      -instruct loadConF(regF dst, immF src) %{
7219      -  match(Set dst src);
     7152 +instruct loadConF(regF dst, immF con) %{
     7153 +  match(Set dst con);
7220 7154    ins_cost(125);
     7155 +  format %{ "FLD_S  ST,[$constantaddress]\t# load from constant table: float=$con\n\t"
     7156 +            "FSTP   $dst" %}
     7157 +  ins_encode %{
     7158 +    __ fld_s($constantaddress($con));
     7159 +    __ fstp_d($dst$$reg);
     7160 +  %}
     7161 +  ins_pipe(fpu_reg_con);
     7162 +%}
7221 7163  
7222      -  format %{ "FLD_S  ST,$src\n\t"
     7164 +// The instruction usage is guarded by predicate in operand immF0().
     7165 +instruct loadConF0(regF dst, immF0 con) %{
     7166 +  match(Set dst con);
     7167 +  ins_cost(125);
     7168 +  format %{ "FLDZ   ST\n\t"
7223 7169              "FSTP   $dst" %}
7224      -  opcode(0xD9, 0x00);       /* D9 /0 */
7225      -  ins_encode(LdImmF(src), Pop_Reg_F(dst) );
7226      -  ins_pipe( fpu_reg_con );
     7170 +  ins_encode %{
     7171 +    __ fldz();
     7172 +    __ fstp_d($dst$$reg);
     7173 +  %}
     7174 +  ins_pipe(fpu_reg_con);
     7175 +%}
     7176 +
     7177 +// The instruction usage is guarded by predicate in operand immF1().
     7178 +instruct loadConF1(regF dst, immF1 con) %{
     7179 +  match(Set dst con);
     7180 +  ins_cost(125);
     7181 +  format %{ "FLD1   ST\n\t"
     7182 +            "FSTP   $dst" %}
     7183 +  ins_encode %{
     7184 +    __ fld1();
     7185 +    __ fstp_d($dst$$reg);
     7186 +  %}
     7187 +  ins_pipe(fpu_reg_con);
7227 7188  %}
7228 7189  
7229 7190  // The instruction usage is guarded by predicate in operand immXF().
7230 7191  instruct loadConX(regX dst, immXF con) %{
7231 7192    match(Set dst con);
7232 7193    ins_cost(125);
7233      -  format %{ "MOVSS  $dst,[$con]" %}
7234      -  ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x10), LdImmX(dst, con));
7235      -  ins_pipe( pipe_slow );
     7194 +  format %{ "MOVSS  $dst,[$constantaddress]\t# load from constant table: float=$con" %}
     7195 +  ins_encode %{
     7196 +    __ movflt($dst$$XMMRegister, $constantaddress($con));
     7197 +  %}
     7198 +  ins_pipe(pipe_slow);
7236 7199  %}
7237 7200  
7238 7201  // The instruction usage is guarded by predicate in operand immXF0().
7239 7202  instruct loadConX0(regX dst, immXF0 src) %{
7240 7203    match(Set dst src);
7241 7204    ins_cost(100);
7242 7205    format %{ "XORPS  $dst,$dst\t# float 0.0" %}
7243      -  ins_encode( Opcode(0x0F), Opcode(0x57), RegReg(dst,dst));
7244      -  ins_pipe( pipe_slow );
     7206 +  ins_encode %{
     7207 +    __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
     7208 +  %}
     7209 +  ins_pipe(pipe_slow);
7245 7210  %}
7246 7211  
7247 7212  // The instruction usage is guarded by predicate in operand immD().
7248      -instruct loadConD(regD dst, immD src) %{
7249      -  match(Set dst src);
     7213 +instruct loadConD(regD dst, immD con) %{
     7214 +  match(Set dst con);
     7215 +  ins_cost(125);
     7216 +
     7217 +  format %{ "FLD_D  ST,[$constantaddress]\t# load from constant table: double=$con\n\t"
     7218 +            "FSTP   $dst" %}
     7219 +  ins_encode %{
     7220 +    __ fld_d($constantaddress($con));
     7221 +    __ fstp_d($dst$$reg);
     7222 +  %}
     7223 +  ins_pipe(fpu_reg_con);
     7224 +%}
     7225 +
     7226 +// The instruction usage is guarded by predicate in operand immD0().
     7227 +instruct loadConD0(regD dst, immD0 con) %{
     7228 +  match(Set dst con);
     7229 +  ins_cost(125);
     7230 +
     7231 +  format %{ "FLDZ   ST\n\t"
     7232 +            "FSTP   $dst" %}
     7233 +  ins_encode %{
     7234 +    __ fldz();
     7235 +    __ fstp_d($dst$$reg);
     7236 +  %}
     7237 +  ins_pipe(fpu_reg_con);
     7238 +%}
     7239 +
     7240 +// The instruction usage is guarded by predicate in operand immD1().
     7241 +instruct loadConD1(regD dst, immD1 con) %{
     7242 +  match(Set dst con);
7250 7243    ins_cost(125);
7251 7244  
7252      -  format %{ "FLD_D  ST,$src\n\t"
     7245 +  format %{ "FLD1   ST\n\t"
7253 7246              "FSTP   $dst" %}
7254      -  ins_encode(LdImmD(src), Pop_Reg_D(dst) );
7255      -  ins_pipe( fpu_reg_con );
     7247 +  ins_encode %{
     7248 +    __ fld1();
     7249 +    __ fstp_d($dst$$reg);
     7250 +  %}
     7251 +  ins_pipe(fpu_reg_con);
7256 7252  %}
7257 7253  
7258 7254  // The instruction usage is guarded by predicate in operand immXD().
7259 7255  instruct loadConXD(regXD dst, immXD con) %{
7260 7256    match(Set dst con);
7261 7257    ins_cost(125);
7262      -  format %{ "MOVSD  $dst,[$con]" %}
7263      -  ins_encode(load_conXD(dst, con));
7264      -  ins_pipe( pipe_slow );
     7258 +  format %{ "MOVSD  $dst,[$constantaddress]\t# load from constant table: double=$con" %}
     7259 +  ins_encode %{
     7260 +    __ movdbl($dst$$XMMRegister, $constantaddress($con));
     7261 +  %}
     7262 +  ins_pipe(pipe_slow);
7265 7263  %}
7266 7264  
7267 7265  // The instruction usage is guarded by predicate in operand immXD0().
7268 7266  instruct loadConXD0(regXD dst, immXD0 src) %{
7269 7267    match(Set dst src);
7270 7268    ins_cost(100);
7271 7269    format %{ "XORPD  $dst,$dst\t# double 0.0" %}
7272 7270    ins_encode( Opcode(0x66), Opcode(0x0F), Opcode(0x57), RegReg(dst,dst));
7273 7271    ins_pipe( pipe_slow );
7274 7272  %}
↓ open down ↓ 3021 lines elided ↑ open up ↑
10296 10294              "DADD   ST,$src\n\t"
10297 10295              "FST_D  $dst" %}
10298 10296    opcode(0xDD, 0x0);
10299 10297    ins_encode( Opcode(0xDD), RMopc_Mem(0x00,dst),
10300 10298                Opcode(0xD8), RegOpc(src),
10301 10299                set_instruction_start,
10302 10300                Opcode(0xDD), RMopc_Mem(0x03,dst) );
10303 10301    ins_pipe( fpu_reg_mem );
10304 10302  %}
10305 10303  
10306      -instruct addD_reg_imm1(regD dst, immD1 src) %{
     10304 +instruct addD_reg_imm1(regD dst, immD1 con) %{
10307 10305    predicate(UseSSE<=1);
10308      -  match(Set dst (AddD dst src));
     10306 +  match(Set dst (AddD dst con));
10309 10307    ins_cost(125);
10310 10308    format %{ "FLD1\n\t"
10311 10309              "DADDp  $dst,ST" %}
10312      -  opcode(0xDE, 0x00);
10313      -  ins_encode( LdImmD(src),
10314      -              OpcP, RegOpc(dst) );
10315      -  ins_pipe( fpu_reg );
     10310 +  ins_encode %{
     10311 +    __ fld1();
     10312 +    __ faddp($dst$$reg);
     10313 +  %}
     10314 +  ins_pipe(fpu_reg);
10316 10315  %}
10317 10316  
10318      -instruct addD_reg_imm(regD dst, immD src) %{
     10317 +instruct addD_reg_imm(regD dst, immD con) %{
10319 10318    predicate(UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 );
10320      -  match(Set dst (AddD dst src));
     10319 +  match(Set dst (AddD dst con));
10321 10320    ins_cost(200);
10322      -  format %{ "FLD_D  [$src]\n\t"
     10321 +  format %{ "FLD_D  [$constantaddress]\t# load from constant table: double=$con\n\t"
10323 10322              "DADDp  $dst,ST" %}
10324      -  opcode(0xDE, 0x00);       /* DE /0 */
10325      -  ins_encode( LdImmD(src),
10326      -              OpcP, RegOpc(dst));
10327      -  ins_pipe( fpu_reg_mem );
     10323 +  ins_encode %{
     10324 +    __ fld_d($constantaddress($con));
     10325 +    __ faddp($dst$$reg);
     10326 +  %}
     10327 +  ins_pipe(fpu_reg_mem);
10328 10328  %}
10329 10329  
10330 10330  instruct addD_reg_imm_round(stackSlotD dst, regD src, immD con) %{
10331 10331    predicate(UseSSE<=1 && _kids[0]->_kids[1]->_leaf->getd() != 0.0 && _kids[0]->_kids[1]->_leaf->getd() != 1.0 );
10332 10332    match(Set dst (RoundDouble (AddD src con)));
10333 10333    ins_cost(200);
10334      -  format %{ "FLD_D  [$con]\n\t"
     10334 +  format %{ "FLD_D  [$constantaddress]\t# load from constant table: double=$con\n\t"
10335 10335              "DADD   ST,$src\n\t"
10336 10336              "FSTP_D $dst\t# D-round" %}
10337      -  opcode(0xD8, 0x00);       /* D8 /0 */
10338      -  ins_encode( LdImmD(con),
10339      -              OpcP, RegOpc(src), Pop_Mem_D(dst));
10340      -  ins_pipe( fpu_mem_reg_con );
     10337 +  ins_encode %{
     10338 +    __ fld_d($constantaddress($con));
     10339 +    __ fadd($src$$reg);
     10340 +    __ fstp_d(Address(rsp, $dst$$disp));
     10341 +  %}
     10342 +  ins_pipe(fpu_mem_reg_con);
10341 10343  %}
10342 10344  
10343 10345  // Add two double precision floating point values in xmm
10344 10346  instruct addXD_reg(regXD dst, regXD src) %{
10345 10347    predicate(UseSSE>=2);
10346 10348    match(Set dst (AddD dst src));
10347 10349    format %{ "ADDSD  $dst,$src" %}
10348 10350    ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), RegReg(dst, src));
10349 10351    ins_pipe( pipe_slow );
10350 10352  %}
10351 10353  
10352 10354  instruct addXD_imm(regXD dst, immXD con) %{
10353 10355    predicate(UseSSE>=2);
10354 10356    match(Set dst (AddD dst con));
10355      -  format %{ "ADDSD  $dst,[$con]" %}
10356      -  ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), LdImmXD(dst, con) );
10357      -  ins_pipe( pipe_slow );
     10357 +  format %{ "ADDSD  $dst,[$constantaddress]\t# load from constant table: double=$con" %}
     10358 +  ins_encode %{
     10359 +    __ addsd($dst$$XMMRegister, $constantaddress($con));
     10360 +  %}
     10361 +  ins_pipe(pipe_slow);
10358 10362  %}
10359 10363  
10360 10364  instruct addXD_mem(regXD dst, memory mem) %{
10361 10365    predicate(UseSSE>=2);
10362 10366    match(Set dst (AddD dst (LoadD mem)));
10363 10367    format %{ "ADDSD  $dst,$mem" %}
10364 10368    ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), RegMem(dst,mem));
10365 10369    ins_pipe( pipe_slow );
10366 10370  %}
10367 10371  
↓ open down ↓ 2 lines elided ↑ open up ↑
10370 10374    predicate(UseSSE>=2);
10371 10375    match(Set dst (SubD dst src));
10372 10376    format %{ "SUBSD  $dst,$src" %}
10373 10377    ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), RegReg(dst, src));
10374 10378    ins_pipe( pipe_slow );
10375 10379  %}
10376 10380  
10377 10381  instruct subXD_imm(regXD dst, immXD con) %{
10378 10382    predicate(UseSSE>=2);
10379 10383    match(Set dst (SubD dst con));
10380      -  format %{ "SUBSD  $dst,[$con]" %}
10381      -  ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), LdImmXD(dst, con) );
10382      -  ins_pipe( pipe_slow );
     10384 +  format %{ "SUBSD  $dst,[$constantaddress]\t# load from constant table: double=$con" %}
     10385 +  ins_encode %{
     10386 +    __ subsd($dst$$XMMRegister, $constantaddress($con));
     10387 +  %}
     10388 +  ins_pipe(pipe_slow);
10383 10389  %}
10384 10390  
10385 10391  instruct subXD_mem(regXD dst, memory mem) %{
10386 10392    predicate(UseSSE>=2);
10387 10393    match(Set dst (SubD dst (LoadD mem)));
10388 10394    format %{ "SUBSD  $dst,$mem" %}
10389 10395    ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), RegMem(dst,mem));
10390 10396    ins_pipe( pipe_slow );
10391 10397  %}
10392 10398  
↓ open down ↓ 2 lines elided ↑ open up ↑
10395 10401    predicate(UseSSE>=2);
10396 10402    match(Set dst (MulD dst src));
10397 10403    format %{ "MULSD  $dst,$src" %}
10398 10404    ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), RegReg(dst, src));
10399 10405    ins_pipe( pipe_slow );
10400 10406  %}
10401 10407  
10402 10408  instruct mulXD_imm(regXD dst, immXD con) %{
10403 10409    predicate(UseSSE>=2);
10404 10410    match(Set dst (MulD dst con));
10405      -  format %{ "MULSD  $dst,[$con]" %}
10406      -  ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), LdImmXD(dst, con) );
10407      -  ins_pipe( pipe_slow );
     10411 +  format %{ "MULSD  $dst,[$constantaddress]\t# load from constant table: double=$con" %}
     10412 +  ins_encode %{
     10413 +    __ mulsd($dst$$XMMRegister, $constantaddress($con));
     10414 +  %}
     10415 +  ins_pipe(pipe_slow);
10408 10416  %}
10409 10417  
10410 10418  instruct mulXD_mem(regXD dst, memory mem) %{
10411 10419    predicate(UseSSE>=2);
10412 10420    match(Set dst (MulD dst (LoadD mem)));
10413 10421    format %{ "MULSD  $dst,$mem" %}
10414 10422    ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), RegMem(dst,mem));
10415 10423    ins_pipe( pipe_slow );
10416 10424  %}
10417 10425  
↓ open down ↓ 3 lines elided ↑ open up ↑
10421 10429    match(Set dst (DivD dst src));
10422 10430    format %{ "DIVSD  $dst,$src" %}
10423 10431    opcode(0xF2, 0x0F, 0x5E);
10424 10432    ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), RegReg(dst, src));
10425 10433    ins_pipe( pipe_slow );
10426 10434  %}
10427 10435  
10428 10436  instruct divXD_imm(regXD dst, immXD con) %{
10429 10437    predicate(UseSSE>=2);
10430 10438    match(Set dst (DivD dst con));
10431      -  format %{ "DIVSD  $dst,[$con]" %}
10432      -  ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), LdImmXD(dst, con));
10433      -  ins_pipe( pipe_slow );
     10439 +  format %{ "DIVSD  $dst,[$constantaddress]\t# load from constant table: double=$con" %}
     10440 +  ins_encode %{
     10441 +    __ divsd($dst$$XMMRegister, $constantaddress($con));
     10442 +  %}
     10443 +  ins_pipe(pipe_slow);
10434 10444  %}
10435 10445  
10436 10446  instruct divXD_mem(regXD dst, memory mem) %{
10437 10447    predicate(UseSSE>=2);
10438 10448    match(Set dst (DivD dst (LoadD mem)));
10439 10449    format %{ "DIVSD  $dst,$mem" %}
10440 10450    ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), RegMem(dst,mem));
10441 10451    ins_pipe( pipe_slow );
10442 10452  %}
10443 10453  
↓ open down ↓ 30 lines elided ↑ open up ↑
10474 10484              "FLD    StubRoutines::_fpu_subnormal_bias2\n\t"
10475 10485              "DMULp  $dst,ST\n\t" %}
10476 10486    opcode(0xDE, 0x1); /* DE C8+i or DE /1*/
10477 10487    ins_encode( strictfp_bias1(dst),
10478 10488                Push_Reg_D(src),
10479 10489                OpcP, RegOpc(dst),
10480 10490                strictfp_bias2(dst) );
10481 10491    ins_pipe( fpu_reg_reg );
10482 10492  %}
10483 10493  
10484      -instruct mulD_reg_imm(regD dst, immD src) %{
     10494 +instruct mulD_reg_imm(regD dst, immD con) %{
10485 10495    predicate( UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 );
10486      -  match(Set dst (MulD dst src));
     10496 +  match(Set dst (MulD dst con));
10487 10497    ins_cost(200);
10488      -  format %{ "FLD_D  [$src]\n\t"
     10498 +  format %{ "FLD_D  [$constantaddress]\t# load from constant table: double=$con\n\t"
10489 10499              "DMULp  $dst,ST" %}
10490      -  opcode(0xDE, 0x1); /* DE /1 */
10491      -  ins_encode( LdImmD(src),
10492      -              OpcP, RegOpc(dst) );
10493      -  ins_pipe( fpu_reg_mem );
     10500 +  ins_encode %{
     10501 +    __ fld_d($constantaddress($con));
     10502 +    __ fmulp($dst$$reg);
     10503 +  %}
     10504 +  ins_pipe(fpu_reg_mem);
10494 10505  %}
10495 10506  
10496 10507  
10497 10508  instruct mulD_reg_mem(regD dst, memory src) %{
10498 10509    predicate( UseSSE<=1 );
10499 10510    match(Set dst (MulD dst (LoadD src)));
10500 10511    ins_cost(200);
10501 10512    format %{ "FLD_D  $src\n\t"
10502 10513              "DMULp  $dst,ST" %}
10503 10514    opcode(0xDE, 0x1, 0xDD); /* DE C8+i or DE /1*/  /* LoadD  DD /0 */
↓ open down ↓ 713 lines elided ↑ open up ↑
11217 11228    predicate(UseSSE>=1);
11218 11229    match(Set dst (AddF dst src));
11219 11230    format %{ "ADDSS  $dst,$src" %}
11220 11231    ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), RegReg(dst, src));
11221 11232    ins_pipe( pipe_slow );
11222 11233  %}
11223 11234  
11224 11235  instruct addX_imm(regX dst, immXF con) %{
11225 11236    predicate(UseSSE>=1);
11226 11237    match(Set dst (AddF dst con));
11227      -  format %{ "ADDSS  $dst,[$con]" %}
11228      -  ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), LdImmX(dst, con) );
11229      -  ins_pipe( pipe_slow );
     11238 +  format %{ "ADDSS  $dst,[$constantaddress]\t# load from constant table: float=$con" %}
     11239 +  ins_encode %{
     11240 +    __ addss($dst$$XMMRegister, $constantaddress($con));
     11241 +  %}
     11242 +  ins_pipe(pipe_slow);
11230 11243  %}
11231 11244  
11232 11245  instruct addX_mem(regX dst, memory mem) %{
11233 11246    predicate(UseSSE>=1);
11234 11247    match(Set dst (AddF dst (LoadF mem)));
11235 11248    format %{ "ADDSS  $dst,$mem" %}
11236 11249    ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), RegMem(dst, mem));
11237 11250    ins_pipe( pipe_slow );
11238 11251  %}
11239 11252  
↓ open down ↓ 2 lines elided ↑ open up ↑
11242 11255    predicate(UseSSE>=1);
11243 11256    match(Set dst (SubF dst src));
11244 11257    format %{ "SUBSS  $dst,$src" %}
11245 11258    ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), RegReg(dst, src));
11246 11259    ins_pipe( pipe_slow );
11247 11260  %}
11248 11261  
11249 11262  instruct subX_imm(regX dst, immXF con) %{
11250 11263    predicate(UseSSE>=1);
11251 11264    match(Set dst (SubF dst con));
11252      -  format %{ "SUBSS  $dst,[$con]" %}
11253      -  ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), LdImmX(dst, con) );
11254      -  ins_pipe( pipe_slow );
     11265 +  format %{ "SUBSS  $dst,[$constantaddress]\t# load from constant table: float=$con" %}
     11266 +  ins_encode %{
     11267 +    __ subss($dst$$XMMRegister, $constantaddress($con));
     11268 +  %}
     11269 +  ins_pipe(pipe_slow);
11255 11270  %}
11256 11271  
11257 11272  instruct subX_mem(regX dst, memory mem) %{
11258 11273    predicate(UseSSE>=1);
11259 11274    match(Set dst (SubF dst (LoadF mem)));
11260 11275    format %{ "SUBSS  $dst,$mem" %}
11261 11276    ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), RegMem(dst,mem));
11262 11277    ins_pipe( pipe_slow );
11263 11278  %}
11264 11279  
↓ open down ↓ 2 lines elided ↑ open up ↑
11267 11282    predicate(UseSSE>=1);
11268 11283    match(Set dst (MulF dst src));
11269 11284    format %{ "MULSS  $dst,$src" %}
11270 11285    ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), RegReg(dst, src));
11271 11286    ins_pipe( pipe_slow );
11272 11287  %}
11273 11288  
11274 11289  instruct mulX_imm(regX dst, immXF con) %{
11275 11290    predicate(UseSSE>=1);
11276 11291    match(Set dst (MulF dst con));
11277      -  format %{ "MULSS  $dst,[$con]" %}
11278      -  ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), LdImmX(dst, con) );
11279      -  ins_pipe( pipe_slow );
     11292 +  format %{ "MULSS  $dst,[$constantaddress]\t# load from constant table: float=$con" %}
     11293 +  ins_encode %{
     11294 +    __ mulss($dst$$XMMRegister, $constantaddress($con));
     11295 +  %}
     11296 +  ins_pipe(pipe_slow);
11280 11297  %}
11281 11298  
11282 11299  instruct mulX_mem(regX dst, memory mem) %{
11283 11300    predicate(UseSSE>=1);
11284 11301    match(Set dst (MulF dst (LoadF mem)));
11285 11302    format %{ "MULSS  $dst,$mem" %}
11286 11303    ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), RegMem(dst,mem));
11287 11304    ins_pipe( pipe_slow );
11288 11305  %}
11289 11306  
↓ open down ↓ 2 lines elided ↑ open up ↑
11292 11309    predicate(UseSSE>=1);
11293 11310    match(Set dst (DivF dst src));
11294 11311    format %{ "DIVSS  $dst,$src" %}
11295 11312    ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), RegReg(dst, src));
11296 11313    ins_pipe( pipe_slow );
11297 11314  %}
11298 11315  
11299 11316  instruct divX_imm(regX dst, immXF con) %{
11300 11317    predicate(UseSSE>=1);
11301 11318    match(Set dst (DivF dst con));
11302      -  format %{ "DIVSS  $dst,[$con]" %}
11303      -  ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), LdImmX(dst, con) );
11304      -  ins_pipe( pipe_slow );
     11319 +  format %{ "DIVSS  $dst,[$constantaddress]\t# load from constant table: float=$con" %}
     11320 +  ins_encode %{
     11321 +    __ divss($dst$$XMMRegister, $constantaddress($con));
     11322 +  %}
     11323 +  ins_pipe(pipe_slow);
11305 11324  %}
11306 11325  
11307 11326  instruct divX_mem(regX dst, memory mem) %{
11308 11327    predicate(UseSSE>=1);
11309 11328    match(Set dst (DivF dst (LoadF mem)));
11310 11329    format %{ "DIVSS  $dst,$mem" %}
11311 11330    ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), RegMem(dst,mem));
11312 11331    ins_pipe( pipe_slow );
11313 11332  %}
11314 11333  
↓ open down ↓ 134 lines elided ↑ open up ↑
11449 11468    opcode(0xD8, 0x0, 0xD9); /* D8 /0 */  /* LoadF  D9 /0 */
11450 11469    ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
11451 11470                set_instruction_start,
11452 11471                OpcP, RMopc_Mem(secondary,src1),
11453 11472                Pop_Mem_F(dst) );
11454 11473    ins_pipe( fpu_mem_mem_mem );
11455 11474  %}
11456 11475  
11457 11476  
11458 11477  // Spill to obtain 24-bit precision
11459      -instruct addF24_reg_imm(stackSlotF dst, regF src1, immF src2) %{
     11478 +instruct addF24_reg_imm(stackSlotF dst, regF src, immF con) %{
11460 11479    predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
11461      -  match(Set dst (AddF src1 src2));
11462      -  format %{ "FLD    $src1\n\t"
11463      -            "FADD   $src2\n\t"
     11480 +  match(Set dst (AddF src con));
     11481 +  format %{ "FLD    $src\n\t"
     11482 +            "FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t"
11464 11483              "FSTP_S $dst"  %}
11465      -  opcode(0xD8, 0x00);       /* D8 /0 */
11466      -  ins_encode( Push_Reg_F(src1),
11467      -              Opc_MemImm_F(src2),
11468      -              Pop_Mem_F(dst));
11469      -  ins_pipe( fpu_mem_reg_con );
     11484 +  ins_encode %{
     11485 +    __ fld_s($src$$reg - 1);  // FLD ST(i-1)
     11486 +    __ fadd_s($constantaddress($con));
     11487 +    __ fstp_s(Address(rsp, $dst$$disp));
     11488 +  %}
     11489 +  ins_pipe(fpu_mem_reg_con);
11470 11490  %}
11471 11491  //
11472 11492  // This instruction does not round to 24-bits
11473      -instruct addF_reg_imm(regF dst, regF src1, immF src2) %{
     11493 +instruct addF_reg_imm(regF dst, regF src, immF con) %{
11474 11494    predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
11475      -  match(Set dst (AddF src1 src2));
11476      -  format %{ "FLD    $src1\n\t"
11477      -            "FADD   $src2\n\t"
11478      -            "FSTP_S $dst"  %}
11479      -  opcode(0xD8, 0x00);       /* D8 /0 */
11480      -  ins_encode( Push_Reg_F(src1),
11481      -              Opc_MemImm_F(src2),
11482      -              Pop_Reg_F(dst));
11483      -  ins_pipe( fpu_reg_reg_con );
     11495 +  match(Set dst (AddF src con));
     11496 +  format %{ "FLD    $src\n\t"
     11497 +            "FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t"
     11498 +            "FSTP   $dst"  %}
     11499 +  ins_encode %{
     11500 +    __ fld_s($src$$reg - 1);  // FLD ST(i-1)
     11501 +    __ fadd_s($constantaddress($con));
     11502 +    __ fstp_d($dst$$reg);
     11503 +  %}
     11504 +  ins_pipe(fpu_reg_reg_con);
11484 11505  %}
11485 11506  
11486 11507  // Spill to obtain 24-bit precision
11487 11508  instruct mulF24_reg(stackSlotF dst, regF src1, regF src2) %{
11488 11509    predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
11489 11510    match(Set dst (MulF src1 src2));
11490 11511  
11491 11512    format %{ "FLD    $src1\n\t"
11492 11513              "FMUL   $src2\n\t"
11493 11514              "FSTP_S $dst"  %}
↓ open down ↓ 58 lines elided ↑ open up ↑
11552 11573    format %{ "FMUL   $dst,$src1,$src2" %}
11553 11574    opcode(0xD8, 0x1, 0xD9); /* D8 /1 */  /* LoadF D9 /0 */
11554 11575    ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
11555 11576                set_instruction_start,
11556 11577                OpcP, RMopc_Mem(secondary,src1),
11557 11578                Pop_Mem_F(dst) );
11558 11579    ins_pipe( fpu_mem_mem_mem );
11559 11580  %}
11560 11581  
11561 11582  // Spill to obtain 24-bit precision
11562      -instruct mulF24_reg_imm(stackSlotF dst, regF src1, immF src2) %{
     11583 +instruct mulF24_reg_imm(stackSlotF dst, regF src, immF con) %{
11563 11584    predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
11564      -  match(Set dst (MulF src1 src2));
     11585 +  match(Set dst (MulF src con));
11565 11586  
11566      -  format %{ "FMULc $dst,$src1,$src2" %}
11567      -  opcode(0xD8, 0x1);  /* D8 /1*/
11568      -  ins_encode( Push_Reg_F(src1),
11569      -              Opc_MemImm_F(src2),
11570      -              Pop_Mem_F(dst));
11571      -  ins_pipe( fpu_mem_reg_con );
     11587 +  format %{ "FLD    $src\n\t"
     11588 +            "FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t"
     11589 +            "FSTP_S $dst"  %}
     11590 +  ins_encode %{
     11591 +    __ fld_s($src$$reg - 1);  // FLD ST(i-1)
     11592 +    __ fmul_s($constantaddress($con));
     11593 +    __ fstp_s(Address(rsp, $dst$$disp));
     11594 +  %}
     11595 +  ins_pipe(fpu_mem_reg_con);
11572 11596  %}
11573 11597  //
11574 11598  // This instruction does not round to 24-bits
11575      -instruct mulF_reg_imm(regF dst, regF src1, immF src2) %{
     11599 +instruct mulF_reg_imm(regF dst, regF src, immF con) %{
11576 11600    predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
11577      -  match(Set dst (MulF src1 src2));
     11601 +  match(Set dst (MulF src con));
11578 11602  
11579      -  format %{ "FMULc $dst. $src1, $src2" %}
11580      -  opcode(0xD8, 0x1);  /* D8 /1*/
11581      -  ins_encode( Push_Reg_F(src1),
11582      -              Opc_MemImm_F(src2),
11583      -              Pop_Reg_F(dst));
11584      -  ins_pipe( fpu_reg_reg_con );
     11603 +  format %{ "FLD    $src\n\t"
     11604 +            "FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t"
     11605 +            "FSTP   $dst"  %}
     11606 +  ins_encode %{
     11607 +    __ fld_s($src$$reg - 1);  // FLD ST(i-1)
     11608 +    __ fmul_s($constantaddress($con));
     11609 +    __ fstp_d($dst$$reg);
     11610 +  %}
     11611 +  ins_pipe(fpu_reg_reg_con);
11585 11612  %}
11586 11613  
11587 11614  
11588 11615  //
11589 11616  // MACRO1 -- subsume unshared load into mulF
11590 11617  // This instruction does not round to 24-bits
11591 11618  instruct mulF_reg_load1(regF dst, regF src, memory mem1 ) %{
11592 11619    predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
11593 11620    match(Set dst (MulF (LoadF mem1) src));
11594 11621  
↓ open down ↓ 1337 lines elided ↑ open up ↑
12932 12959    ins_encode( max_enc(dst,src) );
12933 12960    ins_pipe( pipe_slow );
12934 12961  %}
12935 12962  
12936 12963  // ============================================================================
12937 12964  // Branch Instructions
12938 12965  // Jump Table
12939 12966  instruct jumpXtnd(eRegI switch_val) %{
12940 12967    match(Jump switch_val);
12941 12968    ins_cost(350);
12942      -
12943      -  format %{  "JMP    [table_base](,$switch_val,1)\n\t" %}
12944      -
     12969 +  format %{  "JMP    [$constantaddress](,$switch_val,1)\n\t" %}
12945 12970    ins_encode %{
12946      -    address table_base  = __ address_table_constant(_index2label);
12947      -
12948 12971      // Jump to Address(table_base + switch_reg)
12949      -    InternalAddress table(table_base);
12950 12972      Address index(noreg, $switch_val$$Register, Address::times_1);
12951      -    __ jump(ArrayAddress(table, index));
     12973 +    __ jump(ArrayAddress($constantaddress, index));
12952 12974    %}
12953 12975    ins_pc_relative(1);
12954 12976    ins_pipe(pipe_jmp);
12955 12977  %}
12956 12978  
12957 12979  // Jump Direct - Label defines a relative address from JMP+1
12958 12980  instruct jmpDir(label labl) %{
12959 12981    match(Goto);
12960 12982    effect(USE labl);
12961 12983  
↓ open down ↓ 1104 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX