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