src/cpu/x86/vm/x86_32.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6961690 Sdiff src/cpu/x86/vm

src/cpu/x86/vm/x86_32.ad

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:


 490   if( dst_encoding == src_encoding ) {
 491     // reg-reg copy, use an empty encoding
 492   } else {
 493     emit_opcode( cbuf, 0x8B );
 494     emit_rm(cbuf, 0x3, dst_encoding, src_encoding );
 495   }
 496 }
 497 
 498 void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) {
 499   if( dst_encoding == src_encoding ) {
 500     // reg-reg copy, use an empty encoding
 501   } else {
 502     MacroAssembler _masm(&cbuf);
 503 
 504     __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding));
 505   }
 506 }
 507 
 508 
 509 //=============================================================================
























 510 #ifndef PRODUCT
 511 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
 512   Compile* C = ra_->C;
 513   if( C->in_24_bit_fp_mode() ) {
 514     st->print("FLDCW  24 bit fpu control word");
 515     st->print_cr(""); st->print("\t");
 516   }
 517 
 518   int framesize = C->frame_slots() << LogBytesPerInt;
 519   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
 520   // Remove two words for return addr and rbp,
 521   framesize -= 2*wordSize;
 522 
 523   // Calls to C2R adapters often do not accept exceptional returns.
 524   // We require that their callers must bang for them.  But be careful, because
 525   // some VM calls (such as call site linkage) can use several kilobytes of
 526   // stack.  But the stack safety zone should account for that.
 527   // See bugs 4446381, 4468289, 4497237.
 528   if (C->need_stack_bang(framesize)) {
 529     st->print_cr("# stack bang"); st->print("\t");


1303 // Emit deopt handler code.
1304 int emit_deopt_handler(CodeBuffer& cbuf) {
1305 
1306   // Note that the code buffer's insts_mark is always relative to insts.
1307   // That's why we must use the macroassembler to generate a handler.
1308   MacroAssembler _masm(&cbuf);
1309   address base =
1310   __ start_a_stub(size_exception_handler());
1311   if (base == NULL)  return 0;  // CodeBuffer::expand failed
1312   int offset = __ offset();
1313   InternalAddress here(__ pc());
1314   __ pushptr(here.addr());
1315 
1316   __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
1317   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1318   __ end_a_stub();
1319   return offset;
1320 }
1321 
1322 
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 const bool Matcher::match_rule_supported(int opcode) {
1347   if (!has_match_rule(opcode))
1348     return false;
1349 
1350   return true;  // Per default match rules are supported.
1351 }
1352 
1353 int Matcher::regnum_to_fpu_offset(int regnum) {
1354   return regnum - 32; // The FP registers are in the second chunk
1355 }
1356 
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 // This is UltraSparc specific, true just means we have fast l2f conversion
1374 const bool Matcher::convL2FSupported(void) {
1375   return true;
1376 }
1377 
1378 // Vector width in bytes
1379 const uint Matcher::vector_width_in_bytes(void) {
1380   return UseSSE >= 2 ? 8 : 0;
1381 }
1382 
1383 // Vector ideal reg
1384 const uint Matcher::vector_ideal_reg(void) {
1385   return Op_RegD;
1386 }
1387 
1388 // Is this branch offset short enough that a short branch can be used?
1389 //
1390 // NOTE: If the platform does not provide any short branch variants, then
1391 //       this method should return false for offset 0.
1392 bool Matcher::is_short_branch_offset(int rule, int offset) {


2019       emit_d32(cbuf, src_con);
2020     }
2021   %}
2022 
2023   enc_class LdImmL_Hi( eRegL dst, immL src) %{    // Load Immediate
2024     // Load immediate does not have a zero or sign extended version
2025     // for 8-bit immediates
2026     int dst_enc = $dst$$reg + 2;
2027     int src_con = ((julong)($src$$constant)) >> 32;
2028     if (src_con == 0) {
2029       // xor dst, dst
2030       emit_opcode(cbuf, 0x33);
2031       emit_rm(cbuf, 0x3, dst_enc, dst_enc);
2032     } else {
2033       emit_opcode(cbuf, $primary + dst_enc);
2034       emit_d32(cbuf, src_con);
2035     }
2036   %}
2037 
2038 
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   enc_class MovI2X_reg(regX dst, eRegI src) %{
2101     emit_opcode(cbuf, 0x66 );     // MOVD dst,src
2102     emit_opcode(cbuf, 0x0F );
2103     emit_opcode(cbuf, 0x6E );
2104     emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
2105   %}
2106 
2107   enc_class MovX2I_reg(eRegI dst, regX src) %{
2108     emit_opcode(cbuf, 0x66 );     // MOVD dst,src
2109     emit_opcode(cbuf, 0x0F );
2110     emit_opcode(cbuf, 0x7E );
2111     emit_rm(cbuf, 0x3, $src$$reg, $dst$$reg);
2112   %}
2113 
2114   enc_class MovL2XD_reg(regXD dst, eRegL src, regXD tmp) %{
2115     { // MOVD $dst,$src.lo
2116       emit_opcode(cbuf,0x66);
2117       emit_opcode(cbuf,0x0F);
2118       emit_opcode(cbuf,0x6E);
2119       emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);


4784   predicate(n->get_long() == (int)(n->get_long()));
4785   match(ConL);
4786   op_cost(20);
4787 
4788   format %{ %}
4789   interface(CONST_INTER);
4790 %}
4791 
4792 //Double Immediate zero
4793 operand immD0() %{
4794   // Do additional (and counter-intuitive) test against NaN to work around VC++
4795   // bug that generates code such that NaNs compare equal to 0.0
4796   predicate( UseSSE<=1 && n->getd() == 0.0 && !g_isnan(n->getd()) );
4797   match(ConD);
4798 
4799   op_cost(5);
4800   format %{ %}
4801   interface(CONST_INTER);
4802 %}
4803 
4804 // Double Immediate
4805 operand immD1() %{
4806   predicate( UseSSE<=1 && n->getd() == 1.0 );
4807   match(ConD);
4808 
4809   op_cost(5);
4810   format %{ %}
4811   interface(CONST_INTER);
4812 %}
4813 
4814 // Double Immediate
4815 operand immD() %{
4816   predicate(UseSSE<=1);
4817   match(ConD);
4818 
4819   op_cost(5);
4820   format %{ %}
4821   interface(CONST_INTER);
4822 %}
4823 
4824 operand immXD() %{


4827 
4828   op_cost(5);
4829   format %{ %}
4830   interface(CONST_INTER);
4831 %}
4832 
4833 // Double Immediate zero
4834 operand immXD0() %{
4835   // Do additional (and counter-intuitive) test against NaN to work around VC++
4836   // bug that generates code such that NaNs compare equal to 0.0 AND do not
4837   // compare equal to -0.0.
4838   predicate( UseSSE>=2 && jlong_cast(n->getd()) == 0 );
4839   match(ConD);
4840 
4841   format %{ %}
4842   interface(CONST_INTER);
4843 %}
4844 
4845 // Float Immediate zero
4846 operand immF0() %{
4847   predicate( UseSSE == 0 && n->getf() == 0.0 );










4848   match(ConF);
4849 
4850   op_cost(5);
4851   format %{ %}
4852   interface(CONST_INTER);
4853 %}
4854 
4855 // Float Immediate
4856 operand immF() %{
4857   predicate( UseSSE == 0 );
4858   match(ConF);
4859 
4860   op_cost(5);
4861   format %{ %}
4862   interface(CONST_INTER);
4863 %}
4864 
4865 // Float Immediate
4866 operand immXF() %{
4867   predicate(UseSSE >= 1);


7198   ins_cost(200);
7199   format %{ "MOV    $dst.lo,$src.lo\n\t"
7200             "MOV    $dst.hi,$src.hi" %}
7201   opcode(0xB8);
7202   ins_encode( LdImmL_Lo(dst, src), LdImmL_Hi(dst, src) );
7203   ins_pipe( ialu_reg_long_fat );
7204 %}
7205 
7206 instruct loadConL0(eRegL dst, immL0 src, eFlagsReg cr) %{
7207   match(Set dst src);
7208   effect(KILL cr);
7209   ins_cost(150);
7210   format %{ "XOR    $dst.lo,$dst.lo\n\t"
7211             "XOR    $dst.hi,$dst.hi" %}
7212   opcode(0x33,0x33);
7213   ins_encode( RegReg_Lo(dst,dst), RegReg_Hi(dst, dst) );
7214   ins_pipe( ialu_reg_long );
7215 %}
7216 
7217 // The instruction usage is guarded by predicate in operand immF().
7218 instruct loadConF(regF dst, immF src) %{
7219   match(Set dst src);
7220   ins_cost(125);








7221 
7222   format %{ "FLD_S  ST,$src\n\t"




7223             "FSTP   $dst" %}
7224   opcode(0xD9, 0x00);       /* D9 /0 */
7225   ins_encode(LdImmF(src), Pop_Reg_F(dst) );
7226   ins_pipe( fpu_reg_con );















7227 %}
7228 
7229 // The instruction usage is guarded by predicate in operand immXF().
7230 instruct loadConX(regX dst, immXF con) %{
7231   match(Set dst con);
7232   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 );


7236 %}
7237 
7238 // The instruction usage is guarded by predicate in operand immXF0().
7239 instruct loadConX0(regX dst, immXF0 src) %{
7240   match(Set dst src);
7241   ins_cost(100);
7242   format %{ "XORPS  $dst,$dst\t# float 0.0" %}
7243   ins_encode( Opcode(0x0F), Opcode(0x57), RegReg(dst,dst));
7244   ins_pipe( pipe_slow );


7245 %}
7246 
7247 // The instruction usage is guarded by predicate in operand immD().
7248 instruct loadConD(regD dst, immD src) %{
7249   match(Set dst src);
7250   ins_cost(125);
7251 
7252   format %{ "FLD_D  ST,$src\n\t"
7253             "FSTP   $dst" %}
7254   ins_encode(LdImmD(src), Pop_Reg_D(dst) );
7255   ins_pipe( fpu_reg_con );































7256 %}
7257 
7258 // The instruction usage is guarded by predicate in operand immXD().
7259 instruct loadConXD(regXD dst, immXD con) %{
7260   match(Set dst con);
7261   ins_cost(125);
7262   format %{ "MOVSD  $dst,[$con]" %}
7263   ins_encode(load_conXD(dst, con));
7264   ins_pipe( pipe_slow );


7265 %}
7266 
7267 // The instruction usage is guarded by predicate in operand immXD0().
7268 instruct loadConXD0(regXD dst, immXD0 src) %{
7269   match(Set dst src);
7270   ins_cost(100);
7271   format %{ "XORPD  $dst,$dst\t# double 0.0" %}
7272   ins_encode( Opcode(0x66), Opcode(0x0F), Opcode(0x57), RegReg(dst,dst));
7273   ins_pipe( pipe_slow );
7274 %}
7275 
7276 // Load Stack Slot
7277 instruct loadSSI(eRegI dst, stackSlotI src) %{
7278   match(Set dst src);
7279   ins_cost(125);
7280 
7281   format %{ "MOV    $dst,$src" %}
7282   opcode(0x8B);
7283   ins_encode( OpcP, RegMem(dst,src));
7284   ins_pipe( ialu_reg_mem );


10286   ins_pipe( fpu_reg_mem );
10287 %}
10288 
10289 // add-to-memory
10290 instruct addD_mem_reg(memory dst, regD src) %{
10291   predicate(UseSSE<=1);
10292   match(Set dst (StoreD dst (RoundDouble (AddD (LoadD dst) src))));
10293   ins_cost(150);
10294 
10295   format %{ "FLD_D  $dst\n\t"
10296             "DADD   ST,$src\n\t"
10297             "FST_D  $dst" %}
10298   opcode(0xDD, 0x0);
10299   ins_encode( Opcode(0xDD), RMopc_Mem(0x00,dst),
10300               Opcode(0xD8), RegOpc(src),
10301               set_instruction_start,
10302               Opcode(0xDD), RMopc_Mem(0x03,dst) );
10303   ins_pipe( fpu_reg_mem );
10304 %}
10305 
10306 instruct addD_reg_imm1(regD dst, immD1 src) %{
10307   predicate(UseSSE<=1);
10308   match(Set dst (AddD dst src));
10309   ins_cost(125);
10310   format %{ "FLD1\n\t"
10311             "DADDp  $dst,ST" %}
10312   opcode(0xDE, 0x00);
10313   ins_encode( LdImmD(src),
10314               OpcP, RegOpc(dst) );
10315   ins_pipe( fpu_reg );

10316 %}
10317 
10318 instruct addD_reg_imm(regD dst, immD src) %{
10319   predicate(UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 );
10320   match(Set dst (AddD dst src));
10321   ins_cost(200);
10322   format %{ "FLD_D  [$src]\n\t"
10323             "DADDp  $dst,ST" %}
10324   opcode(0xDE, 0x00);       /* DE /0 */
10325   ins_encode( LdImmD(src),
10326               OpcP, RegOpc(dst));
10327   ins_pipe( fpu_reg_mem );

10328 %}
10329 
10330 instruct addD_reg_imm_round(stackSlotD dst, regD src, immD con) %{
10331   predicate(UseSSE<=1 && _kids[0]->_kids[1]->_leaf->getd() != 0.0 && _kids[0]->_kids[1]->_leaf->getd() != 1.0 );
10332   match(Set dst (RoundDouble (AddD src con)));
10333   ins_cost(200);
10334   format %{ "FLD_D  [$con]\n\t"
10335             "DADD   ST,$src\n\t"
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 );


10341 %}
10342 
10343 // Add two double precision floating point values in xmm
10344 instruct addXD_reg(regXD dst, regXD src) %{
10345   predicate(UseSSE>=2);
10346   match(Set dst (AddD dst src));
10347   format %{ "ADDSD  $dst,$src" %}
10348   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), RegReg(dst, src));
10349   ins_pipe( pipe_slow );
10350 %}
10351 
10352 instruct addXD_imm(regXD dst, immXD con) %{
10353   predicate(UseSSE>=2);
10354   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 );


10358 %}
10359 
10360 instruct addXD_mem(regXD dst, memory mem) %{
10361   predicate(UseSSE>=2);
10362   match(Set dst (AddD dst (LoadD mem)));
10363   format %{ "ADDSD  $dst,$mem" %}
10364   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), RegMem(dst,mem));
10365   ins_pipe( pipe_slow );
10366 %}
10367 
10368 // Sub two double precision floating point values in xmm
10369 instruct subXD_reg(regXD dst, regXD src) %{
10370   predicate(UseSSE>=2);
10371   match(Set dst (SubD dst src));
10372   format %{ "SUBSD  $dst,$src" %}
10373   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), RegReg(dst, src));
10374   ins_pipe( pipe_slow );
10375 %}
10376 
10377 instruct subXD_imm(regXD dst, immXD con) %{
10378   predicate(UseSSE>=2);
10379   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 );


10383 %}
10384 
10385 instruct subXD_mem(regXD dst, memory mem) %{
10386   predicate(UseSSE>=2);
10387   match(Set dst (SubD dst (LoadD mem)));
10388   format %{ "SUBSD  $dst,$mem" %}
10389   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), RegMem(dst,mem));
10390   ins_pipe( pipe_slow );
10391 %}
10392 
10393 // Mul two double precision floating point values in xmm
10394 instruct mulXD_reg(regXD dst, regXD src) %{
10395   predicate(UseSSE>=2);
10396   match(Set dst (MulD dst src));
10397   format %{ "MULSD  $dst,$src" %}
10398   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), RegReg(dst, src));
10399   ins_pipe( pipe_slow );
10400 %}
10401 
10402 instruct mulXD_imm(regXD dst, immXD con) %{
10403   predicate(UseSSE>=2);
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 );


10408 %}
10409 
10410 instruct mulXD_mem(regXD dst, memory mem) %{
10411   predicate(UseSSE>=2);
10412   match(Set dst (MulD dst (LoadD mem)));
10413   format %{ "MULSD  $dst,$mem" %}
10414   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), RegMem(dst,mem));
10415   ins_pipe( pipe_slow );
10416 %}
10417 
10418 // Div two double precision floating point values in xmm
10419 instruct divXD_reg(regXD dst, regXD src) %{
10420   predicate(UseSSE>=2);
10421   match(Set dst (DivD dst src));
10422   format %{ "DIVSD  $dst,$src" %}
10423   opcode(0xF2, 0x0F, 0x5E);
10424   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), RegReg(dst, src));
10425   ins_pipe( pipe_slow );
10426 %}
10427 
10428 instruct divXD_imm(regXD dst, immXD con) %{
10429   predicate(UseSSE>=2);
10430   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 );


10434 %}
10435 
10436 instruct divXD_mem(regXD dst, memory mem) %{
10437   predicate(UseSSE>=2);
10438   match(Set dst (DivD dst (LoadD mem)));
10439   format %{ "DIVSD  $dst,$mem" %}
10440   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), RegMem(dst,mem));
10441   ins_pipe( pipe_slow );
10442 %}
10443 
10444 
10445 instruct mulD_reg(regD dst, regD src) %{
10446   predicate(UseSSE<=1);
10447   match(Set dst (MulD dst src));
10448   format %{ "FLD    $src\n\t"
10449             "DMULp  $dst,ST" %}
10450   opcode(0xDE, 0x1); /* DE C8+i or DE /1*/
10451   ins_cost(150);
10452   ins_encode( Push_Reg_D(src),
10453               OpcP, RegOpc(dst) );


10464 //
10465 instruct strictfp_mulD_reg(regDPR1 dst, regnotDPR1 src) %{
10466   predicate( UseSSE<=1 && Compile::current()->has_method() && Compile::current()->method()->is_strict() );
10467   match(Set dst (MulD dst src));
10468   ins_cost(1);   // Select this instruction for all strict FP double multiplies
10469 
10470   format %{ "FLD    StubRoutines::_fpu_subnormal_bias1\n\t"
10471             "DMULp  $dst,ST\n\t"
10472             "FLD    $src\n\t"
10473             "DMULp  $dst,ST\n\t"
10474             "FLD    StubRoutines::_fpu_subnormal_bias2\n\t"
10475             "DMULp  $dst,ST\n\t" %}
10476   opcode(0xDE, 0x1); /* DE C8+i or DE /1*/
10477   ins_encode( strictfp_bias1(dst),
10478               Push_Reg_D(src),
10479               OpcP, RegOpc(dst),
10480               strictfp_bias2(dst) );
10481   ins_pipe( fpu_reg_reg );
10482 %}
10483 
10484 instruct mulD_reg_imm(regD dst, immD src) %{
10485   predicate( UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 );
10486   match(Set dst (MulD dst src));
10487   ins_cost(200);
10488   format %{ "FLD_D  [$src]\n\t"
10489             "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 %}
10495 
10496 
10497 instruct mulD_reg_mem(regD dst, memory src) %{
10498   predicate( UseSSE<=1 );
10499   match(Set dst (MulD dst (LoadD src)));
10500   ins_cost(200);
10501   format %{ "FLD_D  $src\n\t"
10502             "DMULp  $dst,ST" %}
10503   opcode(0xDE, 0x1, 0xDD); /* DE C8+i or DE /1*/  /* LoadD  DD /0 */
10504   ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src),
10505               OpcP, RegOpc(dst) );
10506   ins_pipe( fpu_reg_mem );
10507 %}
10508 
10509 //
10510 // Cisc-alternate to reg-reg multiply
10511 instruct mulD_reg_mem_cisc(regD dst, regD src, memory mem) %{
10512   predicate( UseSSE<=1 );
10513   match(Set dst (MulD src (LoadD mem)));


11207   format %{ "FLD    $src\n\t"
11208             "FADDp  $dst,ST" %}
11209   opcode(0xDE, 0x0); /* DE C0+i or DE /0*/
11210   ins_encode( Push_Reg_F(src),
11211               OpcP, RegOpc(dst) );
11212   ins_pipe( fpu_reg_reg );
11213 %}
11214 
11215 // Add two single precision floating point values in xmm
11216 instruct addX_reg(regX dst, regX src) %{
11217   predicate(UseSSE>=1);
11218   match(Set dst (AddF dst src));
11219   format %{ "ADDSS  $dst,$src" %}
11220   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), RegReg(dst, src));
11221   ins_pipe( pipe_slow );
11222 %}
11223 
11224 instruct addX_imm(regX dst, immXF con) %{
11225   predicate(UseSSE>=1);
11226   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 );


11230 %}
11231 
11232 instruct addX_mem(regX dst, memory mem) %{
11233   predicate(UseSSE>=1);
11234   match(Set dst (AddF dst (LoadF mem)));
11235   format %{ "ADDSS  $dst,$mem" %}
11236   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), RegMem(dst, mem));
11237   ins_pipe( pipe_slow );
11238 %}
11239 
11240 // Subtract two single precision floating point values in xmm
11241 instruct subX_reg(regX dst, regX src) %{
11242   predicate(UseSSE>=1);
11243   match(Set dst (SubF dst src));
11244   format %{ "SUBSS  $dst,$src" %}
11245   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), RegReg(dst, src));
11246   ins_pipe( pipe_slow );
11247 %}
11248 
11249 instruct subX_imm(regX dst, immXF con) %{
11250   predicate(UseSSE>=1);
11251   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 );


11255 %}
11256 
11257 instruct subX_mem(regX dst, memory mem) %{
11258   predicate(UseSSE>=1);
11259   match(Set dst (SubF dst (LoadF mem)));
11260   format %{ "SUBSS  $dst,$mem" %}
11261   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), RegMem(dst,mem));
11262   ins_pipe( pipe_slow );
11263 %}
11264 
11265 // Multiply two single precision floating point values in xmm
11266 instruct mulX_reg(regX dst, regX src) %{
11267   predicate(UseSSE>=1);
11268   match(Set dst (MulF dst src));
11269   format %{ "MULSS  $dst,$src" %}
11270   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), RegReg(dst, src));
11271   ins_pipe( pipe_slow );
11272 %}
11273 
11274 instruct mulX_imm(regX dst, immXF con) %{
11275   predicate(UseSSE>=1);
11276   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 );


11280 %}
11281 
11282 instruct mulX_mem(regX dst, memory mem) %{
11283   predicate(UseSSE>=1);
11284   match(Set dst (MulF dst (LoadF mem)));
11285   format %{ "MULSS  $dst,$mem" %}
11286   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), RegMem(dst,mem));
11287   ins_pipe( pipe_slow );
11288 %}
11289 
11290 // Divide two single precision floating point values in xmm
11291 instruct divX_reg(regX dst, regX src) %{
11292   predicate(UseSSE>=1);
11293   match(Set dst (DivF dst src));
11294   format %{ "DIVSS  $dst,$src" %}
11295   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), RegReg(dst, src));
11296   ins_pipe( pipe_slow );
11297 %}
11298 
11299 instruct divX_imm(regX dst, immXF con) %{
11300   predicate(UseSSE>=1);
11301   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 );


11305 %}
11306 
11307 instruct divX_mem(regX dst, memory mem) %{
11308   predicate(UseSSE>=1);
11309   match(Set dst (DivF dst (LoadF mem)));
11310   format %{ "DIVSS  $dst,$mem" %}
11311   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), RegMem(dst,mem));
11312   ins_pipe( pipe_slow );
11313 %}
11314 
11315 // Get the square root of a single precision floating point values in xmm
11316 instruct sqrtX_reg(regX dst, regX src) %{
11317   predicate(UseSSE>=1);
11318   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
11319   format %{ "SQRTSS $dst,$src" %}
11320   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x51), RegReg(dst, src));
11321   ins_pipe( pipe_slow );
11322 %}
11323 
11324 instruct sqrtX_mem(regX dst, memory mem) %{


11439               Pop_Mem_F(dst) );
11440   ins_pipe( fpu_mem_mem_mem );
11441 %}
11442 
11443 // Spill to obtain 24-bit precision
11444 instruct addF24_mem_mem(stackSlotF dst, memory src1, memory src2) %{
11445   predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
11446   match(Set dst (AddF src1 src2));
11447 
11448   format %{ "FADD   $dst,$src1,$src2" %}
11449   opcode(0xD8, 0x0, 0xD9); /* D8 /0 */  /* LoadF  D9 /0 */
11450   ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
11451               set_instruction_start,
11452               OpcP, RMopc_Mem(secondary,src1),
11453               Pop_Mem_F(dst) );
11454   ins_pipe( fpu_mem_mem_mem );
11455 %}
11456 
11457 
11458 // Spill to obtain 24-bit precision
11459 instruct addF24_reg_imm(stackSlotF dst, regF src1, immF src2) %{
11460   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"
11464             "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 );

11470 %}
11471 //
11472 // This instruction does not round to 24-bits
11473 instruct addF_reg_imm(regF dst, regF src1, immF src2) %{
11474   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 );

11484 %}
11485 
11486 // Spill to obtain 24-bit precision
11487 instruct mulF24_reg(stackSlotF dst, regF src1, regF src2) %{
11488   predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
11489   match(Set dst (MulF src1 src2));
11490 
11491   format %{ "FLD    $src1\n\t"
11492             "FMUL   $src2\n\t"
11493             "FSTP_S $dst"  %}
11494   opcode(0xD8, 0x1); /* D8 C8+i or D8 /1 ;; result in TOS */
11495   ins_encode( Push_Reg_F(src1),
11496               OpcReg_F(src2),
11497               Pop_Mem_F(dst) );
11498   ins_pipe( fpu_mem_reg_reg );
11499 %}
11500 //
11501 // This instruction does not round to 24-bits
11502 instruct mulF_reg(regF dst, regF src1, regF src2) %{
11503   predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());


11542               OpcReg_F(src1),
11543               Pop_Reg_F(dst) );
11544   ins_pipe( fpu_reg_reg_mem );
11545 %}
11546 
11547 // Spill to obtain 24-bit precision
11548 instruct mulF24_mem_mem(stackSlotF dst, memory src1, memory src2) %{
11549   predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
11550   match(Set dst (MulF src1 src2));
11551 
11552   format %{ "FMUL   $dst,$src1,$src2" %}
11553   opcode(0xD8, 0x1, 0xD9); /* D8 /1 */  /* LoadF D9 /0 */
11554   ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
11555               set_instruction_start,
11556               OpcP, RMopc_Mem(secondary,src1),
11557               Pop_Mem_F(dst) );
11558   ins_pipe( fpu_mem_mem_mem );
11559 %}
11560 
11561 // Spill to obtain 24-bit precision
11562 instruct mulF24_reg_imm(stackSlotF dst, regF src1, immF src2) %{
11563   predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
11564   match(Set dst (MulF src1 src2));
11565 
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 );



11572 %}
11573 //
11574 // This instruction does not round to 24-bits
11575 instruct mulF_reg_imm(regF dst, regF src1, immF src2) %{
11576   predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
11577   match(Set dst (MulF src1 src2));
11578 
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 );



11585 %}
11586 
11587 
11588 //
11589 // MACRO1 -- subsume unshared load into mulF
11590 // This instruction does not round to 24-bits
11591 instruct mulF_reg_load1(regF dst, regF src, memory mem1 ) %{
11592   predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
11593   match(Set dst (MulF (LoadF mem1) src));
11594 
11595   format %{ "FLD    $mem1    ===MACRO1===\n\t"
11596             "FMUL   ST,$src\n\t"
11597             "FSTP   $dst" %}
11598   opcode(0xD8, 0x1, 0xD9); /* D8 C8+i or D8 /1 */  /* LoadF D9 /0 */
11599   ins_encode( Opcode(tertiary), RMopc_Mem(0x00,mem1),
11600               OpcReg_F(src),
11601               Pop_Reg_F(dst) );
11602   ins_pipe( fpu_reg_reg_mem );
11603 %}
11604 //


12922 //%}
12923 
12924 // Max Register with Register (generic version)
12925 instruct maxI_eReg(eRegI dst, eRegI src, eFlagsReg flags) %{
12926   match(Set dst (MaxI dst src));
12927   effect(KILL flags);
12928   ins_cost(300);
12929 
12930   format %{ "MAX    $dst,$src" %}
12931   opcode(0xCC);
12932   ins_encode( max_enc(dst,src) );
12933   ins_pipe( pipe_slow );
12934 %}
12935 
12936 // ============================================================================
12937 // Branch Instructions
12938 // Jump Table
12939 instruct jumpXtnd(eRegI switch_val) %{
12940   match(Jump switch_val);
12941   ins_cost(350);
12942 
12943   format %{  "JMP    [table_base](,$switch_val,1)\n\t" %}
12944 
12945   ins_encode %{
12946     address table_base  = __ address_table_constant(_index2label);
12947 
12948     // Jump to Address(table_base + switch_reg)
12949     InternalAddress table(table_base);
12950     Address index(noreg, $switch_val$$Register, Address::times_1);
12951     __ jump(ArrayAddress(table, index));
12952   %}
12953   ins_pc_relative(1);
12954   ins_pipe(pipe_jmp);
12955 %}
12956 
12957 // Jump Direct - Label defines a relative address from JMP+1
12958 instruct jmpDir(label labl) %{
12959   match(Goto);
12960   effect(USE labl);
12961 
12962   ins_cost(300);
12963   format %{ "JMP    $labl" %}
12964   size(5);
12965   opcode(0xE9);
12966   ins_encode( OpcP, Lbl( labl ) );
12967   ins_pipe( pipe_jmp );
12968   ins_pc_relative(1);
12969 %}
12970 
12971 // Jump Direct Conditional - Label defines a relative address from Jcc+1




 490   if( dst_encoding == src_encoding ) {
 491     // reg-reg copy, use an empty encoding
 492   } else {
 493     emit_opcode( cbuf, 0x8B );
 494     emit_rm(cbuf, 0x3, dst_encoding, src_encoding );
 495   }
 496 }
 497 
 498 void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) {
 499   if( dst_encoding == src_encoding ) {
 500     // reg-reg copy, use an empty encoding
 501   } else {
 502     MacroAssembler _masm(&cbuf);
 503 
 504     __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding));
 505   }
 506 }
 507 
 508 
 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 //=============================================================================
 534 #ifndef PRODUCT
 535 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
 536   Compile* C = ra_->C;
 537   if( C->in_24_bit_fp_mode() ) {
 538     st->print("FLDCW  24 bit fpu control word");
 539     st->print_cr(""); st->print("\t");
 540   }
 541 
 542   int framesize = C->frame_slots() << LogBytesPerInt;
 543   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
 544   // Remove two words for return addr and rbp,
 545   framesize -= 2*wordSize;
 546 
 547   // Calls to C2R adapters often do not accept exceptional returns.
 548   // We require that their callers must bang for them.  But be careful, because
 549   // some VM calls (such as call site linkage) can use several kilobytes of
 550   // stack.  But the stack safety zone should account for that.
 551   // See bugs 4446381, 4468289, 4497237.
 552   if (C->need_stack_bang(framesize)) {
 553     st->print_cr("# stack bang"); st->print("\t");


1327 // Emit deopt handler code.
1328 int emit_deopt_handler(CodeBuffer& cbuf) {
1329 
1330   // Note that the code buffer's insts_mark is always relative to insts.
1331   // That's why we must use the macroassembler to generate a handler.
1332   MacroAssembler _masm(&cbuf);
1333   address base =
1334   __ start_a_stub(size_exception_handler());
1335   if (base == NULL)  return 0;  // CodeBuffer::expand failed
1336   int offset = __ offset();
1337   InternalAddress here(__ pc());
1338   __ pushptr(here.addr());
1339 
1340   __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
1341   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1342   __ end_a_stub();
1343   return offset;
1344 }
1345 
1346 























1347 const bool Matcher::match_rule_supported(int opcode) {
1348   if (!has_match_rule(opcode))
1349     return false;
1350 
1351   return true;  // Per default match rules are supported.
1352 }
1353 
1354 int Matcher::regnum_to_fpu_offset(int regnum) {
1355   return regnum - 32; // The FP registers are in the second chunk
1356 }
1357 
















1358 // This is UltraSparc specific, true just means we have fast l2f conversion
1359 const bool Matcher::convL2FSupported(void) {
1360   return true;
1361 }
1362 
1363 // Vector width in bytes
1364 const uint Matcher::vector_width_in_bytes(void) {
1365   return UseSSE >= 2 ? 8 : 0;
1366 }
1367 
1368 // Vector ideal reg
1369 const uint Matcher::vector_ideal_reg(void) {
1370   return Op_RegD;
1371 }
1372 
1373 // Is this branch offset short enough that a short branch can be used?
1374 //
1375 // NOTE: If the platform does not provide any short branch variants, then
1376 //       this method should return false for offset 0.
1377 bool Matcher::is_short_branch_offset(int rule, int offset) {


2004       emit_d32(cbuf, src_con);
2005     }
2006   %}
2007 
2008   enc_class LdImmL_Hi( eRegL dst, immL src) %{    // Load Immediate
2009     // Load immediate does not have a zero or sign extended version
2010     // for 8-bit immediates
2011     int dst_enc = $dst$$reg + 2;
2012     int src_con = ((julong)($src$$constant)) >> 32;
2013     if (src_con == 0) {
2014       // xor dst, dst
2015       emit_opcode(cbuf, 0x33);
2016       emit_rm(cbuf, 0x3, dst_enc, dst_enc);
2017     } else {
2018       emit_opcode(cbuf, $primary + dst_enc);
2019       emit_d32(cbuf, src_con);
2020     }
2021   %}
2022 
2023 





























































2024   enc_class MovI2X_reg(regX dst, eRegI src) %{
2025     emit_opcode(cbuf, 0x66 );     // MOVD dst,src
2026     emit_opcode(cbuf, 0x0F );
2027     emit_opcode(cbuf, 0x6E );
2028     emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
2029   %}
2030 
2031   enc_class MovX2I_reg(eRegI dst, regX src) %{
2032     emit_opcode(cbuf, 0x66 );     // MOVD dst,src
2033     emit_opcode(cbuf, 0x0F );
2034     emit_opcode(cbuf, 0x7E );
2035     emit_rm(cbuf, 0x3, $src$$reg, $dst$$reg);
2036   %}
2037 
2038   enc_class MovL2XD_reg(regXD dst, eRegL src, regXD tmp) %{
2039     { // MOVD $dst,$src.lo
2040       emit_opcode(cbuf,0x66);
2041       emit_opcode(cbuf,0x0F);
2042       emit_opcode(cbuf,0x6E);
2043       emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);


4708   predicate(n->get_long() == (int)(n->get_long()));
4709   match(ConL);
4710   op_cost(20);
4711 
4712   format %{ %}
4713   interface(CONST_INTER);
4714 %}
4715 
4716 //Double Immediate zero
4717 operand immD0() %{
4718   // Do additional (and counter-intuitive) test against NaN to work around VC++
4719   // bug that generates code such that NaNs compare equal to 0.0
4720   predicate( UseSSE<=1 && n->getd() == 0.0 && !g_isnan(n->getd()) );
4721   match(ConD);
4722 
4723   op_cost(5);
4724   format %{ %}
4725   interface(CONST_INTER);
4726 %}
4727 
4728 // Double Immediate one
4729 operand immD1() %{
4730   predicate( UseSSE<=1 && n->getd() == 1.0 );
4731   match(ConD);
4732 
4733   op_cost(5);
4734   format %{ %}
4735   interface(CONST_INTER);
4736 %}
4737 
4738 // Double Immediate
4739 operand immD() %{
4740   predicate(UseSSE<=1);
4741   match(ConD);
4742 
4743   op_cost(5);
4744   format %{ %}
4745   interface(CONST_INTER);
4746 %}
4747 
4748 operand immXD() %{


4751 
4752   op_cost(5);
4753   format %{ %}
4754   interface(CONST_INTER);
4755 %}
4756 
4757 // Double Immediate zero
4758 operand immXD0() %{
4759   // Do additional (and counter-intuitive) test against NaN to work around VC++
4760   // bug that generates code such that NaNs compare equal to 0.0 AND do not
4761   // compare equal to -0.0.
4762   predicate( UseSSE>=2 && jlong_cast(n->getd()) == 0 );
4763   match(ConD);
4764 
4765   format %{ %}
4766   interface(CONST_INTER);
4767 %}
4768 
4769 // Float Immediate zero
4770 operand immF0() %{
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);
4782   match(ConF);
4783 
4784   op_cost(5);
4785   format %{ %}
4786   interface(CONST_INTER);
4787 %}
4788 
4789 // Float Immediate
4790 operand immF() %{
4791   predicate( UseSSE == 0 );
4792   match(ConF);
4793 
4794   op_cost(5);
4795   format %{ %}
4796   interface(CONST_INTER);
4797 %}
4798 
4799 // Float Immediate
4800 operand immXF() %{
4801   predicate(UseSSE >= 1);


7132   ins_cost(200);
7133   format %{ "MOV    $dst.lo,$src.lo\n\t"
7134             "MOV    $dst.hi,$src.hi" %}
7135   opcode(0xB8);
7136   ins_encode( LdImmL_Lo(dst, src), LdImmL_Hi(dst, src) );
7137   ins_pipe( ialu_reg_long_fat );
7138 %}
7139 
7140 instruct loadConL0(eRegL dst, immL0 src, eFlagsReg cr) %{
7141   match(Set dst src);
7142   effect(KILL cr);
7143   ins_cost(150);
7144   format %{ "XOR    $dst.lo,$dst.lo\n\t"
7145             "XOR    $dst.hi,$dst.hi" %}
7146   opcode(0x33,0x33);
7147   ins_encode( RegReg_Lo(dst,dst), RegReg_Hi(dst, dst) );
7148   ins_pipe( ialu_reg_long );
7149 %}
7150 
7151 // The instruction usage is guarded by predicate in operand immF().
7152 instruct loadConF(regF dst, immF con) %{
7153   match(Set dst con);
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 %}
7163 
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"
7169             "FSTP   $dst" %}
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);
7188 %}
7189 
7190 // The instruction usage is guarded by predicate in operand immXF().
7191 instruct loadConX(regX dst, immXF con) %{
7192   match(Set dst con);
7193   ins_cost(125);
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);
7199 %}
7200 
7201 // The instruction usage is guarded by predicate in operand immXF0().
7202 instruct loadConX0(regX dst, immXF0 src) %{
7203   match(Set dst src);
7204   ins_cost(100);
7205   format %{ "XORPS  $dst,$dst\t# float 0.0" %}
7206   ins_encode %{
7207     __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
7208   %}
7209   ins_pipe(pipe_slow);
7210 %}
7211 
7212 // The instruction usage is guarded by predicate in operand immD().
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);
7243   ins_cost(125);
7244 
7245   format %{ "FLD1   ST\n\t"
7246             "FSTP   $dst" %}
7247   ins_encode %{
7248     __ fld1();
7249     __ fstp_d($dst$$reg);
7250   %}
7251   ins_pipe(fpu_reg_con);
7252 %}
7253 
7254 // The instruction usage is guarded by predicate in operand immXD().
7255 instruct loadConXD(regXD dst, immXD con) %{
7256   match(Set dst con);
7257   ins_cost(125);
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);
7263 %}
7264 
7265 // The instruction usage is guarded by predicate in operand immXD0().
7266 instruct loadConXD0(regXD dst, immXD0 src) %{
7267   match(Set dst src);
7268   ins_cost(100);
7269   format %{ "XORPD  $dst,$dst\t# double 0.0" %}
7270   ins_encode( Opcode(0x66), Opcode(0x0F), Opcode(0x57), RegReg(dst,dst));
7271   ins_pipe( pipe_slow );
7272 %}
7273 
7274 // Load Stack Slot
7275 instruct loadSSI(eRegI dst, stackSlotI src) %{
7276   match(Set dst src);
7277   ins_cost(125);
7278 
7279   format %{ "MOV    $dst,$src" %}
7280   opcode(0x8B);
7281   ins_encode( OpcP, RegMem(dst,src));
7282   ins_pipe( ialu_reg_mem );


10284   ins_pipe( fpu_reg_mem );
10285 %}
10286 
10287 // add-to-memory
10288 instruct addD_mem_reg(memory dst, regD src) %{
10289   predicate(UseSSE<=1);
10290   match(Set dst (StoreD dst (RoundDouble (AddD (LoadD dst) src))));
10291   ins_cost(150);
10292 
10293   format %{ "FLD_D  $dst\n\t"
10294             "DADD   ST,$src\n\t"
10295             "FST_D  $dst" %}
10296   opcode(0xDD, 0x0);
10297   ins_encode( Opcode(0xDD), RMopc_Mem(0x00,dst),
10298               Opcode(0xD8), RegOpc(src),
10299               set_instruction_start,
10300               Opcode(0xDD), RMopc_Mem(0x03,dst) );
10301   ins_pipe( fpu_reg_mem );
10302 %}
10303 
10304 instruct addD_reg_imm1(regD dst, immD1 con) %{
10305   predicate(UseSSE<=1);
10306   match(Set dst (AddD dst con));
10307   ins_cost(125);
10308   format %{ "FLD1\n\t"
10309             "DADDp  $dst,ST" %}
10310   ins_encode %{
10311     __ fld1();
10312     __ faddp($dst$$reg);
10313   %}
10314   ins_pipe(fpu_reg);
10315 %}
10316 
10317 instruct addD_reg_imm(regD dst, immD con) %{
10318   predicate(UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 );
10319   match(Set dst (AddD dst con));
10320   ins_cost(200);
10321   format %{ "FLD_D  [$constantaddress]\t# load from constant table: double=$con\n\t"
10322             "DADDp  $dst,ST" %}
10323   ins_encode %{
10324     __ fld_d($constantaddress($con));
10325     __ faddp($dst$$reg);
10326   %}
10327   ins_pipe(fpu_reg_mem);
10328 %}
10329 
10330 instruct addD_reg_imm_round(stackSlotD dst, regD src, immD con) %{
10331   predicate(UseSSE<=1 && _kids[0]->_kids[1]->_leaf->getd() != 0.0 && _kids[0]->_kids[1]->_leaf->getd() != 1.0 );
10332   match(Set dst (RoundDouble (AddD src con)));
10333   ins_cost(200);
10334   format %{ "FLD_D  [$constantaddress]\t# load from constant table: double=$con\n\t"
10335             "DADD   ST,$src\n\t"
10336             "FSTP_D $dst\t# D-round" %}
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);
10343 %}
10344 
10345 // Add two double precision floating point values in xmm
10346 instruct addXD_reg(regXD dst, regXD src) %{
10347   predicate(UseSSE>=2);
10348   match(Set dst (AddD dst src));
10349   format %{ "ADDSD  $dst,$src" %}
10350   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), RegReg(dst, src));
10351   ins_pipe( pipe_slow );
10352 %}
10353 
10354 instruct addXD_imm(regXD dst, immXD con) %{
10355   predicate(UseSSE>=2);
10356   match(Set dst (AddD dst con));
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);
10362 %}
10363 
10364 instruct addXD_mem(regXD dst, memory mem) %{
10365   predicate(UseSSE>=2);
10366   match(Set dst (AddD dst (LoadD mem)));
10367   format %{ "ADDSD  $dst,$mem" %}
10368   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), RegMem(dst,mem));
10369   ins_pipe( pipe_slow );
10370 %}
10371 
10372 // Sub two double precision floating point values in xmm
10373 instruct subXD_reg(regXD dst, regXD src) %{
10374   predicate(UseSSE>=2);
10375   match(Set dst (SubD dst src));
10376   format %{ "SUBSD  $dst,$src" %}
10377   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), RegReg(dst, src));
10378   ins_pipe( pipe_slow );
10379 %}
10380 
10381 instruct subXD_imm(regXD dst, immXD con) %{
10382   predicate(UseSSE>=2);
10383   match(Set dst (SubD dst con));
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);
10389 %}
10390 
10391 instruct subXD_mem(regXD dst, memory mem) %{
10392   predicate(UseSSE>=2);
10393   match(Set dst (SubD dst (LoadD mem)));
10394   format %{ "SUBSD  $dst,$mem" %}
10395   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), RegMem(dst,mem));
10396   ins_pipe( pipe_slow );
10397 %}
10398 
10399 // Mul two double precision floating point values in xmm
10400 instruct mulXD_reg(regXD dst, regXD src) %{
10401   predicate(UseSSE>=2);
10402   match(Set dst (MulD dst src));
10403   format %{ "MULSD  $dst,$src" %}
10404   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), RegReg(dst, src));
10405   ins_pipe( pipe_slow );
10406 %}
10407 
10408 instruct mulXD_imm(regXD dst, immXD con) %{
10409   predicate(UseSSE>=2);
10410   match(Set dst (MulD dst con));
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);
10416 %}
10417 
10418 instruct mulXD_mem(regXD dst, memory mem) %{
10419   predicate(UseSSE>=2);
10420   match(Set dst (MulD dst (LoadD mem)));
10421   format %{ "MULSD  $dst,$mem" %}
10422   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), RegMem(dst,mem));
10423   ins_pipe( pipe_slow );
10424 %}
10425 
10426 // Div two double precision floating point values in xmm
10427 instruct divXD_reg(regXD dst, regXD src) %{
10428   predicate(UseSSE>=2);
10429   match(Set dst (DivD dst src));
10430   format %{ "DIVSD  $dst,$src" %}
10431   opcode(0xF2, 0x0F, 0x5E);
10432   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), RegReg(dst, src));
10433   ins_pipe( pipe_slow );
10434 %}
10435 
10436 instruct divXD_imm(regXD dst, immXD con) %{
10437   predicate(UseSSE>=2);
10438   match(Set dst (DivD dst con));
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);
10444 %}
10445 
10446 instruct divXD_mem(regXD dst, memory mem) %{
10447   predicate(UseSSE>=2);
10448   match(Set dst (DivD dst (LoadD mem)));
10449   format %{ "DIVSD  $dst,$mem" %}
10450   ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), RegMem(dst,mem));
10451   ins_pipe( pipe_slow );
10452 %}
10453 
10454 
10455 instruct mulD_reg(regD dst, regD src) %{
10456   predicate(UseSSE<=1);
10457   match(Set dst (MulD dst src));
10458   format %{ "FLD    $src\n\t"
10459             "DMULp  $dst,ST" %}
10460   opcode(0xDE, 0x1); /* DE C8+i or DE /1*/
10461   ins_cost(150);
10462   ins_encode( Push_Reg_D(src),
10463               OpcP, RegOpc(dst) );


10474 //
10475 instruct strictfp_mulD_reg(regDPR1 dst, regnotDPR1 src) %{
10476   predicate( UseSSE<=1 && Compile::current()->has_method() && Compile::current()->method()->is_strict() );
10477   match(Set dst (MulD dst src));
10478   ins_cost(1);   // Select this instruction for all strict FP double multiplies
10479 
10480   format %{ "FLD    StubRoutines::_fpu_subnormal_bias1\n\t"
10481             "DMULp  $dst,ST\n\t"
10482             "FLD    $src\n\t"
10483             "DMULp  $dst,ST\n\t"
10484             "FLD    StubRoutines::_fpu_subnormal_bias2\n\t"
10485             "DMULp  $dst,ST\n\t" %}
10486   opcode(0xDE, 0x1); /* DE C8+i or DE /1*/
10487   ins_encode( strictfp_bias1(dst),
10488               Push_Reg_D(src),
10489               OpcP, RegOpc(dst),
10490               strictfp_bias2(dst) );
10491   ins_pipe( fpu_reg_reg );
10492 %}
10493 
10494 instruct mulD_reg_imm(regD dst, immD con) %{
10495   predicate( UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 );
10496   match(Set dst (MulD dst con));
10497   ins_cost(200);
10498   format %{ "FLD_D  [$constantaddress]\t# load from constant table: double=$con\n\t"
10499             "DMULp  $dst,ST" %}
10500   ins_encode %{
10501     __ fld_d($constantaddress($con));
10502     __ fmulp($dst$$reg);
10503   %}
10504   ins_pipe(fpu_reg_mem);
10505 %}
10506 
10507 
10508 instruct mulD_reg_mem(regD dst, memory src) %{
10509   predicate( UseSSE<=1 );
10510   match(Set dst (MulD dst (LoadD src)));
10511   ins_cost(200);
10512   format %{ "FLD_D  $src\n\t"
10513             "DMULp  $dst,ST" %}
10514   opcode(0xDE, 0x1, 0xDD); /* DE C8+i or DE /1*/  /* LoadD  DD /0 */
10515   ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src),
10516               OpcP, RegOpc(dst) );
10517   ins_pipe( fpu_reg_mem );
10518 %}
10519 
10520 //
10521 // Cisc-alternate to reg-reg multiply
10522 instruct mulD_reg_mem_cisc(regD dst, regD src, memory mem) %{
10523   predicate( UseSSE<=1 );
10524   match(Set dst (MulD src (LoadD mem)));


11218   format %{ "FLD    $src\n\t"
11219             "FADDp  $dst,ST" %}
11220   opcode(0xDE, 0x0); /* DE C0+i or DE /0*/
11221   ins_encode( Push_Reg_F(src),
11222               OpcP, RegOpc(dst) );
11223   ins_pipe( fpu_reg_reg );
11224 %}
11225 
11226 // Add two single precision floating point values in xmm
11227 instruct addX_reg(regX dst, regX src) %{
11228   predicate(UseSSE>=1);
11229   match(Set dst (AddF dst src));
11230   format %{ "ADDSS  $dst,$src" %}
11231   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), RegReg(dst, src));
11232   ins_pipe( pipe_slow );
11233 %}
11234 
11235 instruct addX_imm(regX dst, immXF con) %{
11236   predicate(UseSSE>=1);
11237   match(Set dst (AddF dst con));
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);
11243 %}
11244 
11245 instruct addX_mem(regX dst, memory mem) %{
11246   predicate(UseSSE>=1);
11247   match(Set dst (AddF dst (LoadF mem)));
11248   format %{ "ADDSS  $dst,$mem" %}
11249   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), RegMem(dst, mem));
11250   ins_pipe( pipe_slow );
11251 %}
11252 
11253 // Subtract two single precision floating point values in xmm
11254 instruct subX_reg(regX dst, regX src) %{
11255   predicate(UseSSE>=1);
11256   match(Set dst (SubF dst src));
11257   format %{ "SUBSS  $dst,$src" %}
11258   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), RegReg(dst, src));
11259   ins_pipe( pipe_slow );
11260 %}
11261 
11262 instruct subX_imm(regX dst, immXF con) %{
11263   predicate(UseSSE>=1);
11264   match(Set dst (SubF dst con));
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);
11270 %}
11271 
11272 instruct subX_mem(regX dst, memory mem) %{
11273   predicate(UseSSE>=1);
11274   match(Set dst (SubF dst (LoadF mem)));
11275   format %{ "SUBSS  $dst,$mem" %}
11276   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), RegMem(dst,mem));
11277   ins_pipe( pipe_slow );
11278 %}
11279 
11280 // Multiply two single precision floating point values in xmm
11281 instruct mulX_reg(regX dst, regX src) %{
11282   predicate(UseSSE>=1);
11283   match(Set dst (MulF dst src));
11284   format %{ "MULSS  $dst,$src" %}
11285   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), RegReg(dst, src));
11286   ins_pipe( pipe_slow );
11287 %}
11288 
11289 instruct mulX_imm(regX dst, immXF con) %{
11290   predicate(UseSSE>=1);
11291   match(Set dst (MulF dst con));
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);
11297 %}
11298 
11299 instruct mulX_mem(regX dst, memory mem) %{
11300   predicate(UseSSE>=1);
11301   match(Set dst (MulF dst (LoadF mem)));
11302   format %{ "MULSS  $dst,$mem" %}
11303   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), RegMem(dst,mem));
11304   ins_pipe( pipe_slow );
11305 %}
11306 
11307 // Divide two single precision floating point values in xmm
11308 instruct divX_reg(regX dst, regX src) %{
11309   predicate(UseSSE>=1);
11310   match(Set dst (DivF dst src));
11311   format %{ "DIVSS  $dst,$src" %}
11312   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), RegReg(dst, src));
11313   ins_pipe( pipe_slow );
11314 %}
11315 
11316 instruct divX_imm(regX dst, immXF con) %{
11317   predicate(UseSSE>=1);
11318   match(Set dst (DivF dst con));
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);
11324 %}
11325 
11326 instruct divX_mem(regX dst, memory mem) %{
11327   predicate(UseSSE>=1);
11328   match(Set dst (DivF dst (LoadF mem)));
11329   format %{ "DIVSS  $dst,$mem" %}
11330   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), RegMem(dst,mem));
11331   ins_pipe( pipe_slow );
11332 %}
11333 
11334 // Get the square root of a single precision floating point values in xmm
11335 instruct sqrtX_reg(regX dst, regX src) %{
11336   predicate(UseSSE>=1);
11337   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
11338   format %{ "SQRTSS $dst,$src" %}
11339   ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x51), RegReg(dst, src));
11340   ins_pipe( pipe_slow );
11341 %}
11342 
11343 instruct sqrtX_mem(regX dst, memory mem) %{


11458               Pop_Mem_F(dst) );
11459   ins_pipe( fpu_mem_mem_mem );
11460 %}
11461 
11462 // Spill to obtain 24-bit precision
11463 instruct addF24_mem_mem(stackSlotF dst, memory src1, memory src2) %{
11464   predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
11465   match(Set dst (AddF src1 src2));
11466 
11467   format %{ "FADD   $dst,$src1,$src2" %}
11468   opcode(0xD8, 0x0, 0xD9); /* D8 /0 */  /* LoadF  D9 /0 */
11469   ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
11470               set_instruction_start,
11471               OpcP, RMopc_Mem(secondary,src1),
11472               Pop_Mem_F(dst) );
11473   ins_pipe( fpu_mem_mem_mem );
11474 %}
11475 
11476 
11477 // Spill to obtain 24-bit precision
11478 instruct addF24_reg_imm(stackSlotF dst, regF src, immF con) %{
11479   predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
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"
11483             "FSTP_S $dst"  %}
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);
11490 %}
11491 //
11492 // This instruction does not round to 24-bits
11493 instruct addF_reg_imm(regF dst, regF src, immF con) %{
11494   predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
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);
11505 %}
11506 
11507 // Spill to obtain 24-bit precision
11508 instruct mulF24_reg(stackSlotF dst, regF src1, regF src2) %{
11509   predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
11510   match(Set dst (MulF src1 src2));
11511 
11512   format %{ "FLD    $src1\n\t"
11513             "FMUL   $src2\n\t"
11514             "FSTP_S $dst"  %}
11515   opcode(0xD8, 0x1); /* D8 C8+i or D8 /1 ;; result in TOS */
11516   ins_encode( Push_Reg_F(src1),
11517               OpcReg_F(src2),
11518               Pop_Mem_F(dst) );
11519   ins_pipe( fpu_mem_reg_reg );
11520 %}
11521 //
11522 // This instruction does not round to 24-bits
11523 instruct mulF_reg(regF dst, regF src1, regF src2) %{
11524   predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());


11563               OpcReg_F(src1),
11564               Pop_Reg_F(dst) );
11565   ins_pipe( fpu_reg_reg_mem );
11566 %}
11567 
11568 // Spill to obtain 24-bit precision
11569 instruct mulF24_mem_mem(stackSlotF dst, memory src1, memory src2) %{
11570   predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
11571   match(Set dst (MulF src1 src2));
11572 
11573   format %{ "FMUL   $dst,$src1,$src2" %}
11574   opcode(0xD8, 0x1, 0xD9); /* D8 /1 */  /* LoadF D9 /0 */
11575   ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2),
11576               set_instruction_start,
11577               OpcP, RMopc_Mem(secondary,src1),
11578               Pop_Mem_F(dst) );
11579   ins_pipe( fpu_mem_mem_mem );
11580 %}
11581 
11582 // Spill to obtain 24-bit precision
11583 instruct mulF24_reg_imm(stackSlotF dst, regF src, immF con) %{
11584   predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
11585   match(Set dst (MulF src con));
11586 
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);
11596 %}
11597 //
11598 // This instruction does not round to 24-bits
11599 instruct mulF_reg_imm(regF dst, regF src, immF con) %{
11600   predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
11601   match(Set dst (MulF src con));
11602 
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);
11612 %}
11613 
11614 
11615 //
11616 // MACRO1 -- subsume unshared load into mulF
11617 // This instruction does not round to 24-bits
11618 instruct mulF_reg_load1(regF dst, regF src, memory mem1 ) %{
11619   predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
11620   match(Set dst (MulF (LoadF mem1) src));
11621 
11622   format %{ "FLD    $mem1    ===MACRO1===\n\t"
11623             "FMUL   ST,$src\n\t"
11624             "FSTP   $dst" %}
11625   opcode(0xD8, 0x1, 0xD9); /* D8 C8+i or D8 /1 */  /* LoadF D9 /0 */
11626   ins_encode( Opcode(tertiary), RMopc_Mem(0x00,mem1),
11627               OpcReg_F(src),
11628               Pop_Reg_F(dst) );
11629   ins_pipe( fpu_reg_reg_mem );
11630 %}
11631 //


12949 //%}
12950 
12951 // Max Register with Register (generic version)
12952 instruct maxI_eReg(eRegI dst, eRegI src, eFlagsReg flags) %{
12953   match(Set dst (MaxI dst src));
12954   effect(KILL flags);
12955   ins_cost(300);
12956 
12957   format %{ "MAX    $dst,$src" %}
12958   opcode(0xCC);
12959   ins_encode( max_enc(dst,src) );
12960   ins_pipe( pipe_slow );
12961 %}
12962 
12963 // ============================================================================
12964 // Branch Instructions
12965 // Jump Table
12966 instruct jumpXtnd(eRegI switch_val) %{
12967   match(Jump switch_val);
12968   ins_cost(350);
12969   format %{  "JMP    [$constantaddress](,$switch_val,1)\n\t" %}


12970   ins_encode %{


12971     // Jump to Address(table_base + switch_reg)

12972     Address index(noreg, $switch_val$$Register, Address::times_1);
12973     __ jump(ArrayAddress($constantaddress, index));
12974   %}
12975   ins_pc_relative(1);
12976   ins_pipe(pipe_jmp);
12977 %}
12978 
12979 // Jump Direct - Label defines a relative address from JMP+1
12980 instruct jmpDir(label labl) %{
12981   match(Goto);
12982   effect(USE labl);
12983 
12984   ins_cost(300);
12985   format %{ "JMP    $labl" %}
12986   size(5);
12987   opcode(0xE9);
12988   ins_encode( OpcP, Lbl( labl ) );
12989   ins_pipe( pipe_jmp );
12990   ins_pc_relative(1);
12991 %}
12992 
12993 // Jump Direct Conditional - Label defines a relative address from Jcc+1


src/cpu/x86/vm/x86_32.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File