comparison src/cpu/x86/vm/x86_32.ad @ 2008:2f644f85485d

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: never, kvn
author twisti
date Fri, 03 Dec 2010 01:34:31 -0800
parents 2fe998383789
children 6bbaedb03534
comparison
equal deleted inserted replaced
2007:5ddfcf4b079e 2008:2f644f85485d
505 } 505 }
506 } 506 }
507 507
508 508
509 //============================================================================= 509 //=============================================================================
510 const bool Matcher::constant_table_absolute_addressing = true;
511 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
512
513 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
514 // Empty encoding
515 }
516
517 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
518 return 0;
519 }
520
521 #ifndef PRODUCT
522 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
523 st->print("# MachConstantBaseNode (empty encoding)");
524 }
525 #endif
526
527
528 //=============================================================================
510 #ifndef PRODUCT 529 #ifndef PRODUCT
511 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { 530 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
512 Compile* C = ra_->C; 531 Compile* C = ra_->C;
513 if( C->in_24_bit_fp_mode() ) { 532 if( C->in_24_bit_fp_mode() ) {
514 st->print("FLDCW 24 bit fpu control word"); 533 st->print("FLDCW 24 bit fpu control word");
1318 __ end_a_stub(); 1337 __ end_a_stub();
1319 return offset; 1338 return offset;
1320 } 1339 }
1321 1340
1322 1341
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) { 1342 const bool Matcher::match_rule_supported(int opcode) {
1347 if (!has_match_rule(opcode)) 1343 if (!has_match_rule(opcode))
1348 return false; 1344 return false;
1349 1345
1350 return true; // Per default match rules are supported. 1346 return true; // Per default match rules are supported.
1351 } 1347 }
1352 1348
1353 int Matcher::regnum_to_fpu_offset(int regnum) { 1349 int Matcher::regnum_to_fpu_offset(int regnum) {
1354 return regnum - 32; // The FP registers are in the second chunk 1350 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 } 1351 }
1372 1352
1373 // This is UltraSparc specific, true just means we have fast l2f conversion 1353 // This is UltraSparc specific, true just means we have fast l2f conversion
1374 const bool Matcher::convL2FSupported(void) { 1354 const bool Matcher::convL2FSupported(void) {
1375 return true; 1355 return true;
2031 emit_rm(cbuf, 0x3, dst_enc, dst_enc); 2011 emit_rm(cbuf, 0x3, dst_enc, dst_enc);
2032 } else { 2012 } else {
2033 emit_opcode(cbuf, $primary + dst_enc); 2013 emit_opcode(cbuf, $primary + dst_enc);
2034 emit_d32(cbuf, src_con); 2014 emit_d32(cbuf, src_con);
2035 } 2015 }
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 %} 2016 %}
2098 2017
2099 2018
2100 enc_class MovI2X_reg(regX dst, eRegI src) %{ 2019 enc_class MovI2X_reg(regX dst, eRegI src) %{
2101 emit_opcode(cbuf, 0x66 ); // MOVD dst,src 2020 emit_opcode(cbuf, 0x66 ); // MOVD dst,src
4799 op_cost(5); 4718 op_cost(5);
4800 format %{ %} 4719 format %{ %}
4801 interface(CONST_INTER); 4720 interface(CONST_INTER);
4802 %} 4721 %}
4803 4722
4804 // Double Immediate 4723 // Double Immediate one
4805 operand immD1() %{ 4724 operand immD1() %{
4806 predicate( UseSSE<=1 && n->getd() == 1.0 ); 4725 predicate( UseSSE<=1 && n->getd() == 1.0 );
4807 match(ConD); 4726 match(ConD);
4808 4727
4809 op_cost(5); 4728 op_cost(5);
4842 interface(CONST_INTER); 4761 interface(CONST_INTER);
4843 %} 4762 %}
4844 4763
4845 // Float Immediate zero 4764 // Float Immediate zero
4846 operand immF0() %{ 4765 operand immF0() %{
4847 predicate( UseSSE == 0 && n->getf() == 0.0 ); 4766 predicate(UseSSE == 0 && n->getf() == 0.0F);
4767 match(ConF);
4768
4769 op_cost(5);
4770 format %{ %}
4771 interface(CONST_INTER);
4772 %}
4773
4774 // Float Immediate one
4775 operand immF1() %{
4776 predicate(UseSSE == 0 && n->getf() == 1.0F);
4848 match(ConF); 4777 match(ConF);
4849 4778
4850 op_cost(5); 4779 op_cost(5);
4851 format %{ %} 4780 format %{ %}
4852 interface(CONST_INTER); 4781 interface(CONST_INTER);
7213 ins_encode( RegReg_Lo(dst,dst), RegReg_Hi(dst, dst) ); 7142 ins_encode( RegReg_Lo(dst,dst), RegReg_Hi(dst, dst) );
7214 ins_pipe( ialu_reg_long ); 7143 ins_pipe( ialu_reg_long );
7215 %} 7144 %}
7216 7145
7217 // The instruction usage is guarded by predicate in operand immF(). 7146 // The instruction usage is guarded by predicate in operand immF().
7218 instruct loadConF(regF dst, immF src) %{ 7147 instruct loadConF(regF dst, immF con) %{
7219 match(Set dst src); 7148 match(Set dst con);
7220 ins_cost(125); 7149 ins_cost(125);
7221 7150 format %{ "FLD_S ST,[$constantaddress]\t# load from constant table: float=$con\n\t"
7222 format %{ "FLD_S ST,$src\n\t"
7223 "FSTP $dst" %} 7151 "FSTP $dst" %}
7224 opcode(0xD9, 0x00); /* D9 /0 */ 7152 ins_encode %{
7225 ins_encode(LdImmF(src), Pop_Reg_F(dst) ); 7153 __ fld_s($constantaddress($con));
7226 ins_pipe( fpu_reg_con ); 7154 __ fstp_d($dst$$reg);
7155 %}
7156 ins_pipe(fpu_reg_con);
7157 %}
7158
7159 // The instruction usage is guarded by predicate in operand immF0().
7160 instruct loadConF0(regF dst, immF0 con) %{
7161 match(Set dst con);
7162 ins_cost(125);
7163 format %{ "FLDZ ST\n\t"
7164 "FSTP $dst" %}
7165 ins_encode %{
7166 __ fldz();
7167 __ fstp_d($dst$$reg);
7168 %}
7169 ins_pipe(fpu_reg_con);
7170 %}
7171
7172 // The instruction usage is guarded by predicate in operand immF1().
7173 instruct loadConF1(regF dst, immF1 con) %{
7174 match(Set dst con);
7175 ins_cost(125);
7176 format %{ "FLD1 ST\n\t"
7177 "FSTP $dst" %}
7178 ins_encode %{
7179 __ fld1();
7180 __ fstp_d($dst$$reg);
7181 %}
7182 ins_pipe(fpu_reg_con);
7227 %} 7183 %}
7228 7184
7229 // The instruction usage is guarded by predicate in operand immXF(). 7185 // The instruction usage is guarded by predicate in operand immXF().
7230 instruct loadConX(regX dst, immXF con) %{ 7186 instruct loadConX(regX dst, immXF con) %{
7231 match(Set dst con); 7187 match(Set dst con);
7232 ins_cost(125); 7188 ins_cost(125);
7233 format %{ "MOVSS $dst,[$con]" %} 7189 format %{ "MOVSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
7234 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x10), LdImmX(dst, con)); 7190 ins_encode %{
7235 ins_pipe( pipe_slow ); 7191 __ movflt($dst$$XMMRegister, $constantaddress($con));
7192 %}
7193 ins_pipe(pipe_slow);
7236 %} 7194 %}
7237 7195
7238 // The instruction usage is guarded by predicate in operand immXF0(). 7196 // The instruction usage is guarded by predicate in operand immXF0().
7239 instruct loadConX0(regX dst, immXF0 src) %{ 7197 instruct loadConX0(regX dst, immXF0 src) %{
7240 match(Set dst src); 7198 match(Set dst src);
7241 ins_cost(100); 7199 ins_cost(100);
7242 format %{ "XORPS $dst,$dst\t# float 0.0" %} 7200 format %{ "XORPS $dst,$dst\t# float 0.0" %}
7243 ins_encode( Opcode(0x0F), Opcode(0x57), RegReg(dst,dst)); 7201 ins_encode %{
7244 ins_pipe( pipe_slow ); 7202 __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
7203 %}
7204 ins_pipe(pipe_slow);
7245 %} 7205 %}
7246 7206
7247 // The instruction usage is guarded by predicate in operand immD(). 7207 // The instruction usage is guarded by predicate in operand immD().
7248 instruct loadConD(regD dst, immD src) %{ 7208 instruct loadConD(regD dst, immD con) %{
7249 match(Set dst src); 7209 match(Set dst con);
7250 ins_cost(125); 7210 ins_cost(125);
7251 7211
7252 format %{ "FLD_D ST,$src\n\t" 7212 format %{ "FLD_D ST,[$constantaddress]\t# load from constant table: double=$con\n\t"
7253 "FSTP $dst" %} 7213 "FSTP $dst" %}
7254 ins_encode(LdImmD(src), Pop_Reg_D(dst) ); 7214 ins_encode %{
7255 ins_pipe( fpu_reg_con ); 7215 __ fld_d($constantaddress($con));
7216 __ fstp_d($dst$$reg);
7217 %}
7218 ins_pipe(fpu_reg_con);
7219 %}
7220
7221 // The instruction usage is guarded by predicate in operand immD0().
7222 instruct loadConD0(regD dst, immD0 con) %{
7223 match(Set dst con);
7224 ins_cost(125);
7225
7226 format %{ "FLDZ ST\n\t"
7227 "FSTP $dst" %}
7228 ins_encode %{
7229 __ fldz();
7230 __ fstp_d($dst$$reg);
7231 %}
7232 ins_pipe(fpu_reg_con);
7233 %}
7234
7235 // The instruction usage is guarded by predicate in operand immD1().
7236 instruct loadConD1(regD dst, immD1 con) %{
7237 match(Set dst con);
7238 ins_cost(125);
7239
7240 format %{ "FLD1 ST\n\t"
7241 "FSTP $dst" %}
7242 ins_encode %{
7243 __ fld1();
7244 __ fstp_d($dst$$reg);
7245 %}
7246 ins_pipe(fpu_reg_con);
7256 %} 7247 %}
7257 7248
7258 // The instruction usage is guarded by predicate in operand immXD(). 7249 // The instruction usage is guarded by predicate in operand immXD().
7259 instruct loadConXD(regXD dst, immXD con) %{ 7250 instruct loadConXD(regXD dst, immXD con) %{
7260 match(Set dst con); 7251 match(Set dst con);
7261 ins_cost(125); 7252 ins_cost(125);
7262 format %{ "MOVSD $dst,[$con]" %} 7253 format %{ "MOVSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
7263 ins_encode(load_conXD(dst, con)); 7254 ins_encode %{
7264 ins_pipe( pipe_slow ); 7255 __ movdbl($dst$$XMMRegister, $constantaddress($con));
7256 %}
7257 ins_pipe(pipe_slow);
7265 %} 7258 %}
7266 7259
7267 // The instruction usage is guarded by predicate in operand immXD0(). 7260 // The instruction usage is guarded by predicate in operand immXD0().
7268 instruct loadConXD0(regXD dst, immXD0 src) %{ 7261 instruct loadConXD0(regXD dst, immXD0 src) %{
7269 match(Set dst src); 7262 match(Set dst src);
10301 set_instruction_start, 10294 set_instruction_start,
10302 Opcode(0xDD), RMopc_Mem(0x03,dst) ); 10295 Opcode(0xDD), RMopc_Mem(0x03,dst) );
10303 ins_pipe( fpu_reg_mem ); 10296 ins_pipe( fpu_reg_mem );
10304 %} 10297 %}
10305 10298
10306 instruct addD_reg_imm1(regD dst, immD1 src) %{ 10299 instruct addD_reg_imm1(regD dst, immD1 con) %{
10307 predicate(UseSSE<=1); 10300 predicate(UseSSE<=1);
10308 match(Set dst (AddD dst src)); 10301 match(Set dst (AddD dst con));
10309 ins_cost(125); 10302 ins_cost(125);
10310 format %{ "FLD1\n\t" 10303 format %{ "FLD1\n\t"
10311 "DADDp $dst,ST" %} 10304 "DADDp $dst,ST" %}
10312 opcode(0xDE, 0x00); 10305 ins_encode %{
10313 ins_encode( LdImmD(src), 10306 __ fld1();
10314 OpcP, RegOpc(dst) ); 10307 __ faddp($dst$$reg);
10315 ins_pipe( fpu_reg ); 10308 %}
10316 %} 10309 ins_pipe(fpu_reg);
10317 10310 %}
10318 instruct addD_reg_imm(regD dst, immD src) %{ 10311
10312 instruct addD_reg_imm(regD dst, immD con) %{
10319 predicate(UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 ); 10313 predicate(UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 );
10320 match(Set dst (AddD dst src)); 10314 match(Set dst (AddD dst con));
10321 ins_cost(200); 10315 ins_cost(200);
10322 format %{ "FLD_D [$src]\n\t" 10316 format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t"
10323 "DADDp $dst,ST" %} 10317 "DADDp $dst,ST" %}
10324 opcode(0xDE, 0x00); /* DE /0 */ 10318 ins_encode %{
10325 ins_encode( LdImmD(src), 10319 __ fld_d($constantaddress($con));
10326 OpcP, RegOpc(dst)); 10320 __ faddp($dst$$reg);
10327 ins_pipe( fpu_reg_mem ); 10321 %}
10322 ins_pipe(fpu_reg_mem);
10328 %} 10323 %}
10329 10324
10330 instruct addD_reg_imm_round(stackSlotD dst, regD src, immD con) %{ 10325 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 ); 10326 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))); 10327 match(Set dst (RoundDouble (AddD src con)));
10333 ins_cost(200); 10328 ins_cost(200);
10334 format %{ "FLD_D [$con]\n\t" 10329 format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t"
10335 "DADD ST,$src\n\t" 10330 "DADD ST,$src\n\t"
10336 "FSTP_D $dst\t# D-round" %} 10331 "FSTP_D $dst\t# D-round" %}
10337 opcode(0xD8, 0x00); /* D8 /0 */ 10332 ins_encode %{
10338 ins_encode( LdImmD(con), 10333 __ fld_d($constantaddress($con));
10339 OpcP, RegOpc(src), Pop_Mem_D(dst)); 10334 __ fadd($src$$reg);
10340 ins_pipe( fpu_mem_reg_con ); 10335 __ fstp_d(Address(rsp, $dst$$disp));
10336 %}
10337 ins_pipe(fpu_mem_reg_con);
10341 %} 10338 %}
10342 10339
10343 // Add two double precision floating point values in xmm 10340 // Add two double precision floating point values in xmm
10344 instruct addXD_reg(regXD dst, regXD src) %{ 10341 instruct addXD_reg(regXD dst, regXD src) %{
10345 predicate(UseSSE>=2); 10342 predicate(UseSSE>=2);
10350 %} 10347 %}
10351 10348
10352 instruct addXD_imm(regXD dst, immXD con) %{ 10349 instruct addXD_imm(regXD dst, immXD con) %{
10353 predicate(UseSSE>=2); 10350 predicate(UseSSE>=2);
10354 match(Set dst (AddD dst con)); 10351 match(Set dst (AddD dst con));
10355 format %{ "ADDSD $dst,[$con]" %} 10352 format %{ "ADDSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
10356 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), LdImmXD(dst, con) ); 10353 ins_encode %{
10357 ins_pipe( pipe_slow ); 10354 __ addsd($dst$$XMMRegister, $constantaddress($con));
10355 %}
10356 ins_pipe(pipe_slow);
10358 %} 10357 %}
10359 10358
10360 instruct addXD_mem(regXD dst, memory mem) %{ 10359 instruct addXD_mem(regXD dst, memory mem) %{
10361 predicate(UseSSE>=2); 10360 predicate(UseSSE>=2);
10362 match(Set dst (AddD dst (LoadD mem))); 10361 match(Set dst (AddD dst (LoadD mem)));
10375 %} 10374 %}
10376 10375
10377 instruct subXD_imm(regXD dst, immXD con) %{ 10376 instruct subXD_imm(regXD dst, immXD con) %{
10378 predicate(UseSSE>=2); 10377 predicate(UseSSE>=2);
10379 match(Set dst (SubD dst con)); 10378 match(Set dst (SubD dst con));
10380 format %{ "SUBSD $dst,[$con]" %} 10379 format %{ "SUBSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
10381 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), LdImmXD(dst, con) ); 10380 ins_encode %{
10382 ins_pipe( pipe_slow ); 10381 __ subsd($dst$$XMMRegister, $constantaddress($con));
10382 %}
10383 ins_pipe(pipe_slow);
10383 %} 10384 %}
10384 10385
10385 instruct subXD_mem(regXD dst, memory mem) %{ 10386 instruct subXD_mem(regXD dst, memory mem) %{
10386 predicate(UseSSE>=2); 10387 predicate(UseSSE>=2);
10387 match(Set dst (SubD dst (LoadD mem))); 10388 match(Set dst (SubD dst (LoadD mem)));
10400 %} 10401 %}
10401 10402
10402 instruct mulXD_imm(regXD dst, immXD con) %{ 10403 instruct mulXD_imm(regXD dst, immXD con) %{
10403 predicate(UseSSE>=2); 10404 predicate(UseSSE>=2);
10404 match(Set dst (MulD dst con)); 10405 match(Set dst (MulD dst con));
10405 format %{ "MULSD $dst,[$con]" %} 10406 format %{ "MULSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
10406 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), LdImmXD(dst, con) ); 10407 ins_encode %{
10407 ins_pipe( pipe_slow ); 10408 __ mulsd($dst$$XMMRegister, $constantaddress($con));
10409 %}
10410 ins_pipe(pipe_slow);
10408 %} 10411 %}
10409 10412
10410 instruct mulXD_mem(regXD dst, memory mem) %{ 10413 instruct mulXD_mem(regXD dst, memory mem) %{
10411 predicate(UseSSE>=2); 10414 predicate(UseSSE>=2);
10412 match(Set dst (MulD dst (LoadD mem))); 10415 match(Set dst (MulD dst (LoadD mem)));
10426 %} 10429 %}
10427 10430
10428 instruct divXD_imm(regXD dst, immXD con) %{ 10431 instruct divXD_imm(regXD dst, immXD con) %{
10429 predicate(UseSSE>=2); 10432 predicate(UseSSE>=2);
10430 match(Set dst (DivD dst con)); 10433 match(Set dst (DivD dst con));
10431 format %{ "DIVSD $dst,[$con]" %} 10434 format %{ "DIVSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
10432 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), LdImmXD(dst, con)); 10435 ins_encode %{
10433 ins_pipe( pipe_slow ); 10436 __ divsd($dst$$XMMRegister, $constantaddress($con));
10437 %}
10438 ins_pipe(pipe_slow);
10434 %} 10439 %}
10435 10440
10436 instruct divXD_mem(regXD dst, memory mem) %{ 10441 instruct divXD_mem(regXD dst, memory mem) %{
10437 predicate(UseSSE>=2); 10442 predicate(UseSSE>=2);
10438 match(Set dst (DivD dst (LoadD mem))); 10443 match(Set dst (DivD dst (LoadD mem)));
10479 OpcP, RegOpc(dst), 10484 OpcP, RegOpc(dst),
10480 strictfp_bias2(dst) ); 10485 strictfp_bias2(dst) );
10481 ins_pipe( fpu_reg_reg ); 10486 ins_pipe( fpu_reg_reg );
10482 %} 10487 %}
10483 10488
10484 instruct mulD_reg_imm(regD dst, immD src) %{ 10489 instruct mulD_reg_imm(regD dst, immD con) %{
10485 predicate( UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 ); 10490 predicate( UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 );
10486 match(Set dst (MulD dst src)); 10491 match(Set dst (MulD dst con));
10487 ins_cost(200); 10492 ins_cost(200);
10488 format %{ "FLD_D [$src]\n\t" 10493 format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t"
10489 "DMULp $dst,ST" %} 10494 "DMULp $dst,ST" %}
10490 opcode(0xDE, 0x1); /* DE /1 */ 10495 ins_encode %{
10491 ins_encode( LdImmD(src), 10496 __ fld_d($constantaddress($con));
10492 OpcP, RegOpc(dst) ); 10497 __ fmulp($dst$$reg);
10493 ins_pipe( fpu_reg_mem ); 10498 %}
10499 ins_pipe(fpu_reg_mem);
10494 %} 10500 %}
10495 10501
10496 10502
10497 instruct mulD_reg_mem(regD dst, memory src) %{ 10503 instruct mulD_reg_mem(regD dst, memory src) %{
10498 predicate( UseSSE<=1 ); 10504 predicate( UseSSE<=1 );
11222 %} 11228 %}
11223 11229
11224 instruct addX_imm(regX dst, immXF con) %{ 11230 instruct addX_imm(regX dst, immXF con) %{
11225 predicate(UseSSE>=1); 11231 predicate(UseSSE>=1);
11226 match(Set dst (AddF dst con)); 11232 match(Set dst (AddF dst con));
11227 format %{ "ADDSS $dst,[$con]" %} 11233 format %{ "ADDSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
11228 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), LdImmX(dst, con) ); 11234 ins_encode %{
11229 ins_pipe( pipe_slow ); 11235 __ addss($dst$$XMMRegister, $constantaddress($con));
11236 %}
11237 ins_pipe(pipe_slow);
11230 %} 11238 %}
11231 11239
11232 instruct addX_mem(regX dst, memory mem) %{ 11240 instruct addX_mem(regX dst, memory mem) %{
11233 predicate(UseSSE>=1); 11241 predicate(UseSSE>=1);
11234 match(Set dst (AddF dst (LoadF mem))); 11242 match(Set dst (AddF dst (LoadF mem)));
11247 %} 11255 %}
11248 11256
11249 instruct subX_imm(regX dst, immXF con) %{ 11257 instruct subX_imm(regX dst, immXF con) %{
11250 predicate(UseSSE>=1); 11258 predicate(UseSSE>=1);
11251 match(Set dst (SubF dst con)); 11259 match(Set dst (SubF dst con));
11252 format %{ "SUBSS $dst,[$con]" %} 11260 format %{ "SUBSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
11253 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), LdImmX(dst, con) ); 11261 ins_encode %{
11254 ins_pipe( pipe_slow ); 11262 __ subss($dst$$XMMRegister, $constantaddress($con));
11263 %}
11264 ins_pipe(pipe_slow);
11255 %} 11265 %}
11256 11266
11257 instruct subX_mem(regX dst, memory mem) %{ 11267 instruct subX_mem(regX dst, memory mem) %{
11258 predicate(UseSSE>=1); 11268 predicate(UseSSE>=1);
11259 match(Set dst (SubF dst (LoadF mem))); 11269 match(Set dst (SubF dst (LoadF mem)));
11272 %} 11282 %}
11273 11283
11274 instruct mulX_imm(regX dst, immXF con) %{ 11284 instruct mulX_imm(regX dst, immXF con) %{
11275 predicate(UseSSE>=1); 11285 predicate(UseSSE>=1);
11276 match(Set dst (MulF dst con)); 11286 match(Set dst (MulF dst con));
11277 format %{ "MULSS $dst,[$con]" %} 11287 format %{ "MULSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
11278 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), LdImmX(dst, con) ); 11288 ins_encode %{
11279 ins_pipe( pipe_slow ); 11289 __ mulss($dst$$XMMRegister, $constantaddress($con));
11290 %}
11291 ins_pipe(pipe_slow);
11280 %} 11292 %}
11281 11293
11282 instruct mulX_mem(regX dst, memory mem) %{ 11294 instruct mulX_mem(regX dst, memory mem) %{
11283 predicate(UseSSE>=1); 11295 predicate(UseSSE>=1);
11284 match(Set dst (MulF dst (LoadF mem))); 11296 match(Set dst (MulF dst (LoadF mem)));
11297 %} 11309 %}
11298 11310
11299 instruct divX_imm(regX dst, immXF con) %{ 11311 instruct divX_imm(regX dst, immXF con) %{
11300 predicate(UseSSE>=1); 11312 predicate(UseSSE>=1);
11301 match(Set dst (DivF dst con)); 11313 match(Set dst (DivF dst con));
11302 format %{ "DIVSS $dst,[$con]" %} 11314 format %{ "DIVSS $dst,[$constantaddress]\t# load from constant table: float=$con" %}
11303 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), LdImmX(dst, con) ); 11315 ins_encode %{
11304 ins_pipe( pipe_slow ); 11316 __ divss($dst$$XMMRegister, $constantaddress($con));
11317 %}
11318 ins_pipe(pipe_slow);
11305 %} 11319 %}
11306 11320
11307 instruct divX_mem(regX dst, memory mem) %{ 11321 instruct divX_mem(regX dst, memory mem) %{
11308 predicate(UseSSE>=1); 11322 predicate(UseSSE>=1);
11309 match(Set dst (DivF dst (LoadF mem))); 11323 match(Set dst (DivF dst (LoadF mem)));
11454 ins_pipe( fpu_mem_mem_mem ); 11468 ins_pipe( fpu_mem_mem_mem );
11455 %} 11469 %}
11456 11470
11457 11471
11458 // Spill to obtain 24-bit precision 11472 // Spill to obtain 24-bit precision
11459 instruct addF24_reg_imm(stackSlotF dst, regF src1, immF src2) %{ 11473 instruct addF24_reg_imm(stackSlotF dst, regF src, immF con) %{
11460 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 11474 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
11461 match(Set dst (AddF src1 src2)); 11475 match(Set dst (AddF src con));
11462 format %{ "FLD $src1\n\t" 11476 format %{ "FLD $src\n\t"
11463 "FADD $src2\n\t" 11477 "FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t"
11464 "FSTP_S $dst" %} 11478 "FSTP_S $dst" %}
11465 opcode(0xD8, 0x00); /* D8 /0 */ 11479 ins_encode %{
11466 ins_encode( Push_Reg_F(src1), 11480 __ fld_s($src$$reg - 1); // FLD ST(i-1)
11467 Opc_MemImm_F(src2), 11481 __ fadd_s($constantaddress($con));
11468 Pop_Mem_F(dst)); 11482 __ fstp_s(Address(rsp, $dst$$disp));
11469 ins_pipe( fpu_mem_reg_con ); 11483 %}
11484 ins_pipe(fpu_mem_reg_con);
11470 %} 11485 %}
11471 // 11486 //
11472 // This instruction does not round to 24-bits 11487 // This instruction does not round to 24-bits
11473 instruct addF_reg_imm(regF dst, regF src1, immF src2) %{ 11488 instruct addF_reg_imm(regF dst, regF src, immF con) %{
11474 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11489 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
11475 match(Set dst (AddF src1 src2)); 11490 match(Set dst (AddF src con));
11476 format %{ "FLD $src1\n\t" 11491 format %{ "FLD $src\n\t"
11477 "FADD $src2\n\t" 11492 "FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t"
11478 "FSTP_S $dst" %} 11493 "FSTP $dst" %}
11479 opcode(0xD8, 0x00); /* D8 /0 */ 11494 ins_encode %{
11480 ins_encode( Push_Reg_F(src1), 11495 __ fld_s($src$$reg - 1); // FLD ST(i-1)
11481 Opc_MemImm_F(src2), 11496 __ fadd_s($constantaddress($con));
11482 Pop_Reg_F(dst)); 11497 __ fstp_d($dst$$reg);
11483 ins_pipe( fpu_reg_reg_con ); 11498 %}
11499 ins_pipe(fpu_reg_reg_con);
11484 %} 11500 %}
11485 11501
11486 // Spill to obtain 24-bit precision 11502 // Spill to obtain 24-bit precision
11487 instruct mulF24_reg(stackSlotF dst, regF src1, regF src2) %{ 11503 instruct mulF24_reg(stackSlotF dst, regF src1, regF src2) %{
11488 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 11504 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
11557 Pop_Mem_F(dst) ); 11573 Pop_Mem_F(dst) );
11558 ins_pipe( fpu_mem_mem_mem ); 11574 ins_pipe( fpu_mem_mem_mem );
11559 %} 11575 %}
11560 11576
11561 // Spill to obtain 24-bit precision 11577 // Spill to obtain 24-bit precision
11562 instruct mulF24_reg_imm(stackSlotF dst, regF src1, immF src2) %{ 11578 instruct mulF24_reg_imm(stackSlotF dst, regF src, immF con) %{
11563 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 11579 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr());
11564 match(Set dst (MulF src1 src2)); 11580 match(Set dst (MulF src con));
11565 11581
11566 format %{ "FMULc $dst,$src1,$src2" %} 11582 format %{ "FLD $src\n\t"
11567 opcode(0xD8, 0x1); /* D8 /1*/ 11583 "FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t"
11568 ins_encode( Push_Reg_F(src1), 11584 "FSTP_S $dst" %}
11569 Opc_MemImm_F(src2), 11585 ins_encode %{
11570 Pop_Mem_F(dst)); 11586 __ fld_s($src$$reg - 1); // FLD ST(i-1)
11571 ins_pipe( fpu_mem_reg_con ); 11587 __ fmul_s($constantaddress($con));
11588 __ fstp_s(Address(rsp, $dst$$disp));
11589 %}
11590 ins_pipe(fpu_mem_reg_con);
11572 %} 11591 %}
11573 // 11592 //
11574 // This instruction does not round to 24-bits 11593 // This instruction does not round to 24-bits
11575 instruct mulF_reg_imm(regF dst, regF src1, immF src2) %{ 11594 instruct mulF_reg_imm(regF dst, regF src, immF con) %{
11576 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11595 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr());
11577 match(Set dst (MulF src1 src2)); 11596 match(Set dst (MulF src con));
11578 11597
11579 format %{ "FMULc $dst. $src1, $src2" %} 11598 format %{ "FLD $src\n\t"
11580 opcode(0xD8, 0x1); /* D8 /1*/ 11599 "FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t"
11581 ins_encode( Push_Reg_F(src1), 11600 "FSTP $dst" %}
11582 Opc_MemImm_F(src2), 11601 ins_encode %{
11583 Pop_Reg_F(dst)); 11602 __ fld_s($src$$reg - 1); // FLD ST(i-1)
11584 ins_pipe( fpu_reg_reg_con ); 11603 __ fmul_s($constantaddress($con));
11604 __ fstp_d($dst$$reg);
11605 %}
11606 ins_pipe(fpu_reg_reg_con);
11585 %} 11607 %}
11586 11608
11587 11609
11588 // 11610 //
11589 // MACRO1 -- subsume unshared load into mulF 11611 // MACRO1 -- subsume unshared load into mulF
12937 // Branch Instructions 12959 // Branch Instructions
12938 // Jump Table 12960 // Jump Table
12939 instruct jumpXtnd(eRegI switch_val) %{ 12961 instruct jumpXtnd(eRegI switch_val) %{
12940 match(Jump switch_val); 12962 match(Jump switch_val);
12941 ins_cost(350); 12963 ins_cost(350);
12942 12964 format %{ "JMP [$constantaddress](,$switch_val,1)\n\t" %}
12943 format %{ "JMP [table_base](,$switch_val,1)\n\t" %}
12944
12945 ins_encode %{ 12965 ins_encode %{
12946 address table_base = __ address_table_constant(_index2label);
12947
12948 // Jump to Address(table_base + switch_reg) 12966 // Jump to Address(table_base + switch_reg)
12949 InternalAddress table(table_base);
12950 Address index(noreg, $switch_val$$Register, Address::times_1); 12967 Address index(noreg, $switch_val$$Register, Address::times_1);
12951 __ jump(ArrayAddress(table, index)); 12968 __ jump(ArrayAddress($constantaddress, index));
12952 %} 12969 %}
12953 ins_pc_relative(1); 12970 ins_pc_relative(1);
12954 ins_pipe(pipe_jmp); 12971 ins_pipe(pipe_jmp);
12955 %} 12972 %}
12956 12973