src/cpu/sparc/vm/sparc.ad

changeset 3001
faa472957b38
parent 2683
7e88bdae86ec
child 3037
3d42f82cd811
equal deleted inserted replaced
2992:b16582d6c7db 3001:faa472957b38
423 423
424 // Paired floating point registers--they show up in the same order as the floats, 424 // Paired floating point registers--they show up in the same order as the floats,
425 // but they are used with the "Op_RegD" type, and always occur in even/odd pairs. 425 // but they are used with the "Op_RegD" type, and always occur in even/odd pairs.
426 // This class is usable for mis-aligned loads as happen in I2C adapters. 426 // This class is usable for mis-aligned loads as happen in I2C adapters.
427 reg_class dflt_low_reg(R_F0, R_F1, R_F2, R_F3, R_F4, R_F5, R_F6, R_F7, R_F8, R_F9, R_F10,R_F11,R_F12,R_F13,R_F14,R_F15, 427 reg_class dflt_low_reg(R_F0, R_F1, R_F2, R_F3, R_F4, R_F5, R_F6, R_F7, R_F8, R_F9, R_F10,R_F11,R_F12,R_F13,R_F14,R_F15,
428 R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23,R_F24,R_F25,R_F26,R_F27,R_F28,R_F29,R_F30,R_F31 ); 428 R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23,R_F24,R_F25,R_F26,R_F27,R_F28,R_F29);
429 %} 429 %}
430 430
431 //----------DEFINITION BLOCK--------------------------------------------------- 431 //----------DEFINITION BLOCK---------------------------------------------------
432 // Define name --> value mappings to inform the ADLC of an integer valued name 432 // Define name --> value mappings to inform the ADLC of an integer valued name
433 // Current support includes integer values in the range [0, 0x7FFFFFFF] 433 // Current support includes integer values in the range [0, 0x7FFFFFFF]
1324 src_second_rc = rc_float; 1324 src_second_rc = rc_float;
1325 } 1325 }
1326 1326
1327 // -------------------------------------- 1327 // --------------------------------------
1328 // Check for float->int copy; requires a trip through memory 1328 // Check for float->int copy; requires a trip through memory
1329 if( src_first_rc == rc_float && dst_first_rc == rc_int ) { 1329 if (src_first_rc == rc_float && dst_first_rc == rc_int && UseVIS < 3) {
1330 int offset = frame::register_save_words*wordSize; 1330 int offset = frame::register_save_words*wordSize;
1331 if( cbuf ) { 1331 if (cbuf) {
1332 emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::sub_op3, R_SP_enc, 16 ); 1332 emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::sub_op3, R_SP_enc, 16 );
1333 impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st); 1333 impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st);
1334 impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st); 1334 impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st);
1335 emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::add_op3, R_SP_enc, 16 ); 1335 emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::add_op3, R_SP_enc, 16 );
1336 } 1336 }
1337 #ifndef PRODUCT 1337 #ifndef PRODUCT
1338 else if( !do_size ) { 1338 else if (!do_size) {
1339 if( size != 0 ) st->print("\n\t"); 1339 if (size != 0) st->print("\n\t");
1340 st->print( "SUB R_SP,16,R_SP\n"); 1340 st->print( "SUB R_SP,16,R_SP\n");
1341 impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st); 1341 impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st);
1342 impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st); 1342 impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st);
1343 st->print("\tADD R_SP,16,R_SP\n"); 1343 st->print("\tADD R_SP,16,R_SP\n");
1344 } 1344 }
1345 #endif 1345 #endif
1346 size += 16; 1346 size += 16;
1347 }
1348
1349 // Check for float->int copy on T4
1350 if (src_first_rc == rc_float && dst_first_rc == rc_int && UseVIS >= 3) {
1351 // Further check for aligned-adjacent pair, so we can use a double move
1352 if ((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second)
1353 return impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mdtox_opf,"MOVDTOX",size, st);
1354 size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mstouw_opf,"MOVSTOUW",size, st);
1355 }
1356 // Check for int->float copy on T4
1357 if (src_first_rc == rc_int && dst_first_rc == rc_float && UseVIS >= 3) {
1358 // Further check for aligned-adjacent pair, so we can use a double move
1359 if ((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second)
1360 return impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mxtod_opf,"MOVXTOD",size, st);
1361 size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mwtos_opf,"MOVWTOS",size, st);
1347 } 1362 }
1348 1363
1349 // -------------------------------------- 1364 // --------------------------------------
1350 // In the 32-bit 1-reg-longs build ONLY, I see mis-aligned long destinations. 1365 // In the 32-bit 1-reg-longs build ONLY, I see mis-aligned long destinations.
1351 // In such cases, I have to do the big-endian swap. For aligned targets, the 1366 // In such cases, I have to do the big-endian swap. For aligned targets, the
8162 "MOVlt $tmp,$p\t! p' < 0 ? p'+y : p'" %} 8177 "MOVlt $tmp,$p\t! p' < 0 ? p'+y : p'" %}
8163 ins_encode( enc_cadd_cmpLTMask(p, q, y, tmp) ); 8178 ins_encode( enc_cadd_cmpLTMask(p, q, y, tmp) );
8164 ins_pipe( cadd_cmpltmask ); 8179 ins_pipe( cadd_cmpltmask );
8165 %} 8180 %}
8166 8181
8182
8183 //-----------------------------------------------------------------
8184 // Direct raw moves between float and general registers using VIS3.
8185
8186 // ins_pipe(faddF_reg);
8187 instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
8188 predicate(UseVIS >= 3);
8189 match(Set dst (MoveF2I src));
8190
8191 format %{ "MOVSTOUW $src,$dst\t! MoveF2I" %}
8192 ins_encode %{
8193 __ movstouw($src$$FloatRegister, $dst$$Register);
8194 %}
8195 ins_pipe(ialu_reg_reg);
8196 %}
8197
8198 instruct MoveI2F_reg_reg(regF dst, iRegI src) %{
8199 predicate(UseVIS >= 3);
8200 match(Set dst (MoveI2F src));
8201
8202 format %{ "MOVWTOS $src,$dst\t! MoveI2F" %}
8203 ins_encode %{
8204 __ movwtos($src$$Register, $dst$$FloatRegister);
8205 %}
8206 ins_pipe(ialu_reg_reg);
8207 %}
8208
8209 instruct MoveD2L_reg_reg(iRegL dst, regD src) %{
8210 predicate(UseVIS >= 3);
8211 match(Set dst (MoveD2L src));
8212
8213 format %{ "MOVDTOX $src,$dst\t! MoveD2L" %}
8214 ins_encode %{
8215 __ movdtox(as_DoubleFloatRegister($src$$reg), $dst$$Register);
8216 %}
8217 ins_pipe(ialu_reg_reg);
8218 %}
8219
8220 instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
8221 predicate(UseVIS >= 3);
8222 match(Set dst (MoveL2D src));
8223
8224 format %{ "MOVXTOD $src,$dst\t! MoveL2D" %}
8225 ins_encode %{
8226 __ movxtod($src$$Register, as_DoubleFloatRegister($dst$$reg));
8227 %}
8228 ins_pipe(ialu_reg_reg);
8229 %}
8230
8231
8232 // Raw moves between float and general registers using stack.
8233
8234 instruct MoveF2I_stack_reg(iRegI dst, stackSlotF src) %{
8235 match(Set dst (MoveF2I src));
8236 effect(DEF dst, USE src);
8237 ins_cost(MEMORY_REF_COST);
8238
8239 size(4);
8240 format %{ "LDUW $src,$dst\t! MoveF2I" %}
8241 opcode(Assembler::lduw_op3);
8242 ins_encode(simple_form3_mem_reg( src, dst ) );
8243 ins_pipe(iload_mem);
8244 %}
8245
8246 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
8247 match(Set dst (MoveI2F src));
8248 effect(DEF dst, USE src);
8249 ins_cost(MEMORY_REF_COST);
8250
8251 size(4);
8252 format %{ "LDF $src,$dst\t! MoveI2F" %}
8253 opcode(Assembler::ldf_op3);
8254 ins_encode(simple_form3_mem_reg(src, dst));
8255 ins_pipe(floadF_stk);
8256 %}
8257
8258 instruct MoveD2L_stack_reg(iRegL dst, stackSlotD src) %{
8259 match(Set dst (MoveD2L src));
8260 effect(DEF dst, USE src);
8261 ins_cost(MEMORY_REF_COST);
8262
8263 size(4);
8264 format %{ "LDX $src,$dst\t! MoveD2L" %}
8265 opcode(Assembler::ldx_op3);
8266 ins_encode(simple_form3_mem_reg( src, dst ) );
8267 ins_pipe(iload_mem);
8268 %}
8269
8270 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
8271 match(Set dst (MoveL2D src));
8272 effect(DEF dst, USE src);
8273 ins_cost(MEMORY_REF_COST);
8274
8275 size(4);
8276 format %{ "LDDF $src,$dst\t! MoveL2D" %}
8277 opcode(Assembler::lddf_op3);
8278 ins_encode(simple_form3_mem_reg(src, dst));
8279 ins_pipe(floadD_stk);
8280 %}
8281
8282 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
8283 match(Set dst (MoveF2I src));
8284 effect(DEF dst, USE src);
8285 ins_cost(MEMORY_REF_COST);
8286
8287 size(4);
8288 format %{ "STF $src,$dst\t! MoveF2I" %}
8289 opcode(Assembler::stf_op3);
8290 ins_encode(simple_form3_mem_reg(dst, src));
8291 ins_pipe(fstoreF_stk_reg);
8292 %}
8293
8294 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
8295 match(Set dst (MoveI2F src));
8296 effect(DEF dst, USE src);
8297 ins_cost(MEMORY_REF_COST);
8298
8299 size(4);
8300 format %{ "STW $src,$dst\t! MoveI2F" %}
8301 opcode(Assembler::stw_op3);
8302 ins_encode(simple_form3_mem_reg( dst, src ) );
8303 ins_pipe(istore_mem_reg);
8304 %}
8305
8306 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
8307 match(Set dst (MoveD2L src));
8308 effect(DEF dst, USE src);
8309 ins_cost(MEMORY_REF_COST);
8310
8311 size(4);
8312 format %{ "STDF $src,$dst\t! MoveD2L" %}
8313 opcode(Assembler::stdf_op3);
8314 ins_encode(simple_form3_mem_reg(dst, src));
8315 ins_pipe(fstoreD_stk_reg);
8316 %}
8317
8318 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
8319 match(Set dst (MoveL2D src));
8320 effect(DEF dst, USE src);
8321 ins_cost(MEMORY_REF_COST);
8322
8323 size(4);
8324 format %{ "STX $src,$dst\t! MoveL2D" %}
8325 opcode(Assembler::stx_op3);
8326 ins_encode(simple_form3_mem_reg( dst, src ) );
8327 ins_pipe(istore_mem_reg);
8328 %}
8329
8330
8167 //----------Arithmetic Conversion Instructions--------------------------------- 8331 //----------Arithmetic Conversion Instructions---------------------------------
8168 // The conversions operations are all Alpha sorted. Please keep it that way! 8332 // The conversions operations are all Alpha sorted. Please keep it that way!
8169 8333
8170 instruct convD2F_reg(regF dst, regD src) %{ 8334 instruct convD2F_reg(regF dst, regD src) %{
8171 match(Set dst (ConvD2F src)); 8335 match(Set dst (ConvD2F src));
8189 "skip:" %} 8353 "skip:" %}
8190 ins_encode(form_d2i_helper(src,dst)); 8354 ins_encode(form_d2i_helper(src,dst));
8191 ins_pipe(fcvtD2I); 8355 ins_pipe(fcvtD2I);
8192 %} 8356 %}
8193 8357
8194 instruct convD2I_reg(stackSlotI dst, regD src) %{ 8358 instruct convD2I_stk(stackSlotI dst, regD src) %{
8195 match(Set dst (ConvD2I src)); 8359 match(Set dst (ConvD2I src));
8196 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); 8360 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST);
8197 expand %{ 8361 expand %{
8198 regF tmp; 8362 regF tmp;
8199 convD2I_helper(tmp, src); 8363 convD2I_helper(tmp, src);
8200 regF_to_stkI(dst, tmp); 8364 regF_to_stkI(dst, tmp);
8201 %} 8365 %}
8202 %} 8366 %}
8367
8368 instruct convD2I_reg(iRegI dst, regD src) %{
8369 predicate(UseVIS >= 3);
8370 match(Set dst (ConvD2I src));
8371 ins_cost(DEFAULT_COST*2 + BRANCH_COST);
8372 expand %{
8373 regF tmp;
8374 convD2I_helper(tmp, src);
8375 MoveF2I_reg_reg(dst, tmp);
8376 %}
8377 %}
8378
8203 8379
8204 // Convert a double to a long in a double register. 8380 // Convert a double to a long in a double register.
8205 // If the double is a NAN, stuff a zero in instead. 8381 // If the double is a NAN, stuff a zero in instead.
8206 instruct convD2L_helper(regD dst, regD src, flagsRegF0 fcc0) %{ 8382 instruct convD2L_helper(regD dst, regD src, flagsRegF0 fcc0) %{
8207 effect(DEF dst, USE src, KILL fcc0); 8383 effect(DEF dst, USE src, KILL fcc0);
8213 "skip:" %} 8389 "skip:" %}
8214 ins_encode(form_d2l_helper(src,dst)); 8390 ins_encode(form_d2l_helper(src,dst));
8215 ins_pipe(fcvtD2L); 8391 ins_pipe(fcvtD2L);
8216 %} 8392 %}
8217 8393
8218 8394 instruct convD2L_stk(stackSlotL dst, regD src) %{
8219 // Double to Long conversion
8220 instruct convD2L_reg(stackSlotL dst, regD src) %{
8221 match(Set dst (ConvD2L src)); 8395 match(Set dst (ConvD2L src));
8222 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); 8396 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST);
8223 expand %{ 8397 expand %{
8224 regD tmp; 8398 regD tmp;
8225 convD2L_helper(tmp, src); 8399 convD2L_helper(tmp, src);
8226 regD_to_stkL(dst, tmp); 8400 regD_to_stkL(dst, tmp);
8227 %} 8401 %}
8228 %} 8402 %}
8229 8403
8404 instruct convD2L_reg(iRegL dst, regD src) %{
8405 predicate(UseVIS >= 3);
8406 match(Set dst (ConvD2L src));
8407 ins_cost(DEFAULT_COST*2 + BRANCH_COST);
8408 expand %{
8409 regD tmp;
8410 convD2L_helper(tmp, src);
8411 MoveD2L_reg_reg(dst, tmp);
8412 %}
8413 %}
8414
8230 8415
8231 instruct convF2D_reg(regD dst, regF src) %{ 8416 instruct convF2D_reg(regD dst, regF src) %{
8232 match(Set dst (ConvF2D src)); 8417 match(Set dst (ConvF2D src));
8233 format %{ "FSTOD $src,$dst" %} 8418 format %{ "FSTOD $src,$dst" %}
8234 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fstod_opf); 8419 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fstod_opf);
8235 ins_encode(form3_opf_rs2F_rdD(src, dst)); 8420 ins_encode(form3_opf_rs2F_rdD(src, dst));
8236 ins_pipe(fcvtF2D); 8421 ins_pipe(fcvtF2D);
8237 %} 8422 %}
8238 8423
8239 8424
8425 // Convert a float to an int in a float register.
8426 // If the float is a NAN, stuff a zero in instead.
8240 instruct convF2I_helper(regF dst, regF src, flagsRegF0 fcc0) %{ 8427 instruct convF2I_helper(regF dst, regF src, flagsRegF0 fcc0) %{
8241 effect(DEF dst, USE src, KILL fcc0); 8428 effect(DEF dst, USE src, KILL fcc0);
8242 format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t" 8429 format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t"
8243 "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t" 8430 "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t"
8244 "FSTOI $src,$dst\t! convert in delay slot\n\t" 8431 "FSTOI $src,$dst\t! convert in delay slot\n\t"
8247 "skip:" %} 8434 "skip:" %}
8248 ins_encode(form_f2i_helper(src,dst)); 8435 ins_encode(form_f2i_helper(src,dst));
8249 ins_pipe(fcvtF2I); 8436 ins_pipe(fcvtF2I);
8250 %} 8437 %}
8251 8438
8252 instruct convF2I_reg(stackSlotI dst, regF src) %{ 8439 instruct convF2I_stk(stackSlotI dst, regF src) %{
8253 match(Set dst (ConvF2I src)); 8440 match(Set dst (ConvF2I src));
8254 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); 8441 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST);
8255 expand %{ 8442 expand %{
8256 regF tmp; 8443 regF tmp;
8257 convF2I_helper(tmp, src); 8444 convF2I_helper(tmp, src);
8258 regF_to_stkI(dst, tmp); 8445 regF_to_stkI(dst, tmp);
8259 %} 8446 %}
8260 %} 8447 %}
8261 8448
8262 8449 instruct convF2I_reg(iRegI dst, regF src) %{
8450 predicate(UseVIS >= 3);
8451 match(Set dst (ConvF2I src));
8452 ins_cost(DEFAULT_COST*2 + BRANCH_COST);
8453 expand %{
8454 regF tmp;
8455 convF2I_helper(tmp, src);
8456 MoveF2I_reg_reg(dst, tmp);
8457 %}
8458 %}
8459
8460
8461 // Convert a float to a long in a float register.
8462 // If the float is a NAN, stuff a zero in instead.
8263 instruct convF2L_helper(regD dst, regF src, flagsRegF0 fcc0) %{ 8463 instruct convF2L_helper(regD dst, regF src, flagsRegF0 fcc0) %{
8264 effect(DEF dst, USE src, KILL fcc0); 8464 effect(DEF dst, USE src, KILL fcc0);
8265 format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t" 8465 format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t"
8266 "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t" 8466 "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t"
8267 "FSTOX $src,$dst\t! convert in delay slot\n\t" 8467 "FSTOX $src,$dst\t! convert in delay slot\n\t"
8270 "skip:" %} 8470 "skip:" %}
8271 ins_encode(form_f2l_helper(src,dst)); 8471 ins_encode(form_f2l_helper(src,dst));
8272 ins_pipe(fcvtF2L); 8472 ins_pipe(fcvtF2L);
8273 %} 8473 %}
8274 8474
8275 // Float to Long conversion 8475 instruct convF2L_stk(stackSlotL dst, regF src) %{
8276 instruct convF2L_reg(stackSlotL dst, regF src) %{
8277 match(Set dst (ConvF2L src)); 8476 match(Set dst (ConvF2L src));
8278 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); 8477 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST);
8279 expand %{ 8478 expand %{
8280 regD tmp; 8479 regD tmp;
8281 convF2L_helper(tmp, src); 8480 convF2L_helper(tmp, src);
8282 regD_to_stkL(dst, tmp); 8481 regD_to_stkL(dst, tmp);
8283 %} 8482 %}
8284 %} 8483 %}
8285 8484
8485 instruct convF2L_reg(iRegL dst, regF src) %{
8486 predicate(UseVIS >= 3);
8487 match(Set dst (ConvF2L src));
8488 ins_cost(DEFAULT_COST*2 + BRANCH_COST);
8489 expand %{
8490 regD tmp;
8491 convF2L_helper(tmp, src);
8492 MoveD2L_reg_reg(dst, tmp);
8493 %}
8494 %}
8495
8286 8496
8287 instruct convI2D_helper(regD dst, regF tmp) %{ 8497 instruct convI2D_helper(regD dst, regF tmp) %{
8288 effect(USE tmp, DEF dst); 8498 effect(USE tmp, DEF dst);
8289 format %{ "FITOD $tmp,$dst" %} 8499 format %{ "FITOD $tmp,$dst" %}
8290 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitod_opf); 8500 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitod_opf);
8291 ins_encode(form3_opf_rs2F_rdD(tmp, dst)); 8501 ins_encode(form3_opf_rs2F_rdD(tmp, dst));
8292 ins_pipe(fcvtI2D); 8502 ins_pipe(fcvtI2D);
8293 %} 8503 %}
8294 8504
8295 instruct convI2D_reg(stackSlotI src, regD dst) %{ 8505 instruct convI2D_stk(stackSlotI src, regD dst) %{
8296 match(Set dst (ConvI2D src)); 8506 match(Set dst (ConvI2D src));
8297 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 8507 ins_cost(DEFAULT_COST + MEMORY_REF_COST);
8298 expand %{ 8508 expand %{
8299 regF tmp; 8509 regF tmp;
8300 stkI_to_regF( tmp, src); 8510 stkI_to_regF(tmp, src);
8301 convI2D_helper( dst, tmp); 8511 convI2D_helper(dst, tmp);
8302 %} 8512 %}
8303 %} 8513 %}
8304 8514
8305 instruct convI2D_mem( regD_low dst, memory mem ) %{ 8515 instruct convI2D_reg(regD_low dst, iRegI src) %{
8516 predicate(UseVIS >= 3);
8517 match(Set dst (ConvI2D src));
8518 expand %{
8519 regF tmp;
8520 MoveI2F_reg_reg(tmp, src);
8521 convI2D_helper(dst, tmp);
8522 %}
8523 %}
8524
8525 instruct convI2D_mem(regD_low dst, memory mem) %{
8306 match(Set dst (ConvI2D (LoadI mem))); 8526 match(Set dst (ConvI2D (LoadI mem)));
8307 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 8527 ins_cost(DEFAULT_COST + MEMORY_REF_COST);
8308 size(8); 8528 size(8);
8309 format %{ "LDF $mem,$dst\n\t" 8529 format %{ "LDF $mem,$dst\n\t"
8310 "FITOD $dst,$dst" %} 8530 "FITOD $dst,$dst" %}
8320 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitos_opf); 8540 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitos_opf);
8321 ins_encode(form3_opf_rs2F_rdF(tmp, dst)); 8541 ins_encode(form3_opf_rs2F_rdF(tmp, dst));
8322 ins_pipe(fcvtI2F); 8542 ins_pipe(fcvtI2F);
8323 %} 8543 %}
8324 8544
8325 instruct convI2F_reg( regF dst, stackSlotI src ) %{ 8545 instruct convI2F_stk(regF dst, stackSlotI src) %{
8326 match(Set dst (ConvI2F src)); 8546 match(Set dst (ConvI2F src));
8327 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 8547 ins_cost(DEFAULT_COST + MEMORY_REF_COST);
8328 expand %{ 8548 expand %{
8329 regF tmp; 8549 regF tmp;
8330 stkI_to_regF(tmp,src); 8550 stkI_to_regF(tmp,src);
8551 convI2F_helper(dst, tmp);
8552 %}
8553 %}
8554
8555 instruct convI2F_reg(regF dst, iRegI src) %{
8556 predicate(UseVIS >= 3);
8557 match(Set dst (ConvI2F src));
8558 ins_cost(DEFAULT_COST);
8559 expand %{
8560 regF tmp;
8561 MoveI2F_reg_reg(tmp, src);
8331 convI2F_helper(dst, tmp); 8562 convI2F_helper(dst, tmp);
8332 %} 8563 %}
8333 %} 8564 %}
8334 8565
8335 instruct convI2F_mem( regF dst, memory mem ) %{ 8566 instruct convI2F_mem( regF dst, memory mem ) %{
8369 size(4); 8600 size(4);
8370 format %{ "SRL $src,0,$dst\t! zero-extend long" %} 8601 format %{ "SRL $src,0,$dst\t! zero-extend long" %}
8371 opcode(Assembler::srl_op3, Assembler::arith_op); 8602 opcode(Assembler::srl_op3, Assembler::arith_op);
8372 ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) ); 8603 ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) );
8373 ins_pipe(ialu_reg_reg); 8604 ins_pipe(ialu_reg_reg);
8374 %}
8375
8376 instruct MoveF2I_stack_reg(iRegI dst, stackSlotF src) %{
8377 match(Set dst (MoveF2I src));
8378 effect(DEF dst, USE src);
8379 ins_cost(MEMORY_REF_COST);
8380
8381 size(4);
8382 format %{ "LDUW $src,$dst\t! MoveF2I" %}
8383 opcode(Assembler::lduw_op3);
8384 ins_encode(simple_form3_mem_reg( src, dst ) );
8385 ins_pipe(iload_mem);
8386 %}
8387
8388 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
8389 match(Set dst (MoveI2F src));
8390 effect(DEF dst, USE src);
8391 ins_cost(MEMORY_REF_COST);
8392
8393 size(4);
8394 format %{ "LDF $src,$dst\t! MoveI2F" %}
8395 opcode(Assembler::ldf_op3);
8396 ins_encode(simple_form3_mem_reg(src, dst));
8397 ins_pipe(floadF_stk);
8398 %}
8399
8400 instruct MoveD2L_stack_reg(iRegL dst, stackSlotD src) %{
8401 match(Set dst (MoveD2L src));
8402 effect(DEF dst, USE src);
8403 ins_cost(MEMORY_REF_COST);
8404
8405 size(4);
8406 format %{ "LDX $src,$dst\t! MoveD2L" %}
8407 opcode(Assembler::ldx_op3);
8408 ins_encode(simple_form3_mem_reg( src, dst ) );
8409 ins_pipe(iload_mem);
8410 %}
8411
8412 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
8413 match(Set dst (MoveL2D src));
8414 effect(DEF dst, USE src);
8415 ins_cost(MEMORY_REF_COST);
8416
8417 size(4);
8418 format %{ "LDDF $src,$dst\t! MoveL2D" %}
8419 opcode(Assembler::lddf_op3);
8420 ins_encode(simple_form3_mem_reg(src, dst));
8421 ins_pipe(floadD_stk);
8422 %}
8423
8424 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
8425 match(Set dst (MoveF2I src));
8426 effect(DEF dst, USE src);
8427 ins_cost(MEMORY_REF_COST);
8428
8429 size(4);
8430 format %{ "STF $src,$dst\t!MoveF2I" %}
8431 opcode(Assembler::stf_op3);
8432 ins_encode(simple_form3_mem_reg(dst, src));
8433 ins_pipe(fstoreF_stk_reg);
8434 %}
8435
8436 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
8437 match(Set dst (MoveI2F src));
8438 effect(DEF dst, USE src);
8439 ins_cost(MEMORY_REF_COST);
8440
8441 size(4);
8442 format %{ "STW $src,$dst\t!MoveI2F" %}
8443 opcode(Assembler::stw_op3);
8444 ins_encode(simple_form3_mem_reg( dst, src ) );
8445 ins_pipe(istore_mem_reg);
8446 %}
8447
8448 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
8449 match(Set dst (MoveD2L src));
8450 effect(DEF dst, USE src);
8451 ins_cost(MEMORY_REF_COST);
8452
8453 size(4);
8454 format %{ "STDF $src,$dst\t!MoveD2L" %}
8455 opcode(Assembler::stdf_op3);
8456 ins_encode(simple_form3_mem_reg(dst, src));
8457 ins_pipe(fstoreD_stk_reg);
8458 %}
8459
8460 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
8461 match(Set dst (MoveL2D src));
8462 effect(DEF dst, USE src);
8463 ins_cost(MEMORY_REF_COST);
8464
8465 size(4);
8466 format %{ "STX $src,$dst\t!MoveL2D" %}
8467 opcode(Assembler::stx_op3);
8468 ins_encode(simple_form3_mem_reg( dst, src ) );
8469 ins_pipe(istore_mem_reg);
8470 %} 8605 %}
8471 8606
8472 8607
8473 //----------- 8608 //-----------
8474 // Long to Double conversion using V8 opcodes. 8609 // Long to Double conversion using V8 opcodes.
8587 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fxtod_opf); 8722 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fxtod_opf);
8588 ins_encode(form3_opf_rs2D_rdD(tmp, dst)); 8723 ins_encode(form3_opf_rs2D_rdD(tmp, dst));
8589 ins_pipe(fcvtL2D); 8724 ins_pipe(fcvtL2D);
8590 %} 8725 %}
8591 8726
8592 instruct convL2D_reg_fast_fxtof(regD dst, stackSlotL src) %{ 8727 instruct convL2D_stk_fast_fxtof(regD dst, stackSlotL src) %{
8593 predicate(VM_Version::has_fast_fxtof()); 8728 predicate(VM_Version::has_fast_fxtof());
8594 match(Set dst (ConvL2D src)); 8729 match(Set dst (ConvL2D src));
8595 ins_cost(DEFAULT_COST + 3 * MEMORY_REF_COST); 8730 ins_cost(DEFAULT_COST + 3 * MEMORY_REF_COST);
8596 expand %{ 8731 expand %{
8597 regD tmp; 8732 regD tmp;
8598 stkL_to_regD(tmp, src); 8733 stkL_to_regD(tmp, src);
8599 convL2D_helper(dst, tmp); 8734 convL2D_helper(dst, tmp);
8600 %} 8735 %}
8601 %} 8736 %}
8602 8737
8603 //----------- 8738 instruct convL2D_reg(regD dst, iRegL src) %{
8604 // Long to Float conversion using V8 opcodes. 8739 predicate(UseVIS >= 3);
8605 // Still useful because cheetah traps and becomes 8740 match(Set dst (ConvL2D src));
8606 // amazingly slow for some common numbers. 8741 expand %{
8742 regD tmp;
8743 MoveL2D_reg_reg(tmp, src);
8744 convL2D_helper(dst, tmp);
8745 %}
8746 %}
8607 8747
8608 // Long to Float conversion using fast fxtof 8748 // Long to Float conversion using fast fxtof
8609 instruct convL2F_helper(regF dst, regD tmp) %{ 8749 instruct convL2F_helper(regF dst, regD tmp) %{
8610 effect(DEF dst, USE tmp); 8750 effect(DEF dst, USE tmp);
8611 size(4); 8751 size(4);
8613 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fxtos_opf); 8753 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fxtos_opf);
8614 ins_encode(form3_opf_rs2D_rdF(tmp, dst)); 8754 ins_encode(form3_opf_rs2D_rdF(tmp, dst));
8615 ins_pipe(fcvtL2F); 8755 ins_pipe(fcvtL2F);
8616 %} 8756 %}
8617 8757
8618 instruct convL2F_reg_fast_fxtof(regF dst, stackSlotL src) %{ 8758 instruct convL2F_stk_fast_fxtof(regF dst, stackSlotL src) %{
8619 match(Set dst (ConvL2F src)); 8759 match(Set dst (ConvL2F src));
8620 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 8760 ins_cost(DEFAULT_COST + MEMORY_REF_COST);
8621 expand %{ 8761 expand %{
8622 regD tmp; 8762 regD tmp;
8623 stkL_to_regD(tmp, src); 8763 stkL_to_regD(tmp, src);
8624 convL2F_helper(dst, tmp); 8764 convL2F_helper(dst, tmp);
8625 %} 8765 %}
8626 %} 8766 %}
8767
8768 instruct convL2F_reg(regF dst, iRegL src) %{
8769 predicate(UseVIS >= 3);
8770 match(Set dst (ConvL2F src));
8771 ins_cost(DEFAULT_COST);
8772 expand %{
8773 regD tmp;
8774 MoveL2D_reg_reg(tmp, src);
8775 convL2F_helper(dst, tmp);
8776 %}
8777 %}
8778
8627 //----------- 8779 //-----------
8628 8780
8629 instruct convL2I_reg(iRegI dst, iRegL src) %{ 8781 instruct convL2I_reg(iRegI dst, iRegL src) %{
8630 match(Set dst (ConvL2I src)); 8782 match(Set dst (ConvL2I src));
8631 #ifndef _LP64 8783 #ifndef _LP64

mercurial