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 |