comparison src/cpu/x86/vm/x86_32.ad @ 624:337400e7a5dd

6797305: Add LoadUB and LoadUI opcode class Summary: Add a LoadUB (unsigned byte) and LoadUI (unsigned int) opcode class so we have these load optimizations in the first place and do not need to handle them in the matcher. Reviewed-by: never, kvn
author twisti
date Mon, 09 Mar 2009 03:17:11 -0700
parents 56aae7be60d4
children 7bb995fbd3c0 c771b7f43bbf
comparison
equal deleted inserted replaced
623:9adddb8c0fc8 624:337400e7a5dd
1 // 1 //
2 // Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. 2 // Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 // 4 //
5 // This code is free software; you can redistribute it and/or modify it 5 // This code is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License version 2 only, as 6 // under the terms of the GNU General Public License version 2 only, as
7 // published by the Free Software Foundation. 7 // published by the Free Software Foundation.
3124 emit_d8 (cbuf,0 ); 3124 emit_d8 (cbuf,0 );
3125 %} 3125 %}
3126 3126
3127 enc_class movq_ld(regXD dst, memory mem) %{ 3127 enc_class movq_ld(regXD dst, memory mem) %{
3128 MacroAssembler _masm(&cbuf); 3128 MacroAssembler _masm(&cbuf);
3129 Address madr = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); 3129 __ movq($dst$$XMMRegister, $mem$$Address);
3130 __ movq(as_XMMRegister($dst$$reg), madr);
3131 %} 3130 %}
3132 3131
3133 enc_class movq_st(memory mem, regXD src) %{ 3132 enc_class movq_st(memory mem, regXD src) %{
3134 MacroAssembler _masm(&cbuf); 3133 MacroAssembler _masm(&cbuf);
3135 Address madr = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); 3134 __ movq($mem$$Address, $src$$XMMRegister);
3136 __ movq(madr, as_XMMRegister($src$$reg));
3137 %} 3135 %}
3138 3136
3139 enc_class pshufd_8x8(regX dst, regX src) %{ 3137 enc_class pshufd_8x8(regX dst, regX src) %{
3140 MacroAssembler _masm(&cbuf); 3138 MacroAssembler _masm(&cbuf);
3141 3139
6394 // Load Byte (8bit signed) 6392 // Load Byte (8bit signed)
6395 instruct loadB(xRegI dst, memory mem) %{ 6393 instruct loadB(xRegI dst, memory mem) %{
6396 match(Set dst (LoadB mem)); 6394 match(Set dst (LoadB mem));
6397 6395
6398 ins_cost(125); 6396 ins_cost(125);
6399 format %{ "MOVSX8 $dst,$mem" %} 6397 format %{ "MOVSX8 $dst,$mem\t# byte" %}
6400 opcode(0xBE, 0x0F); 6398
6401 ins_encode( OpcS, OpcP, RegMem(dst,mem)); 6399 ins_encode %{
6402 ins_pipe( ialu_reg_mem ); 6400 __ movsbl($dst$$Register, $mem$$Address);
6403 %} 6401 %}
6404 6402
6405 // Load Byte (8bit UNsigned) 6403 ins_pipe(ialu_reg_mem);
6406 instruct loadUB(xRegI dst, memory mem, immI_255 bytemask) %{ 6404 %}
6407 match(Set dst (AndI (LoadB mem) bytemask)); 6405
6406 // Load Byte (8bit signed) into Long Register
6407 instruct loadB2L(eRegL dst, memory mem) %{
6408 match(Set dst (ConvI2L (LoadB mem)));
6409
6410 ins_cost(375);
6411 format %{ "MOVSX8 $dst.lo,$mem\t# byte -> long\n\t"
6412 "MOV $dst.hi,$dst.lo\n\t"
6413 "SAR $dst.hi,7" %}
6414
6415 ins_encode %{
6416 __ movsbl($dst$$Register, $mem$$Address);
6417 __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register.
6418 __ sarl(HIGH_FROM_LOW($dst$$Register), 7); // 24+1 MSB are already signed extended.
6419 %}
6420
6421 ins_pipe(ialu_reg_mem);
6422 %}
6423
6424 // Load Unsigned Byte (8bit UNsigned)
6425 instruct loadUB(xRegI dst, memory mem) %{
6426 match(Set dst (LoadUB mem));
6408 6427
6409 ins_cost(125); 6428 ins_cost(125);
6410 format %{ "MOVZX8 $dst,$mem" %} 6429 format %{ "MOVZX8 $dst,$mem\t# ubyte -> int" %}
6411 opcode(0xB6, 0x0F); 6430
6412 ins_encode( OpcS, OpcP, RegMem(dst,mem)); 6431 ins_encode %{
6413 ins_pipe( ialu_reg_mem ); 6432 __ movzbl($dst$$Register, $mem$$Address);
6433 %}
6434
6435 ins_pipe(ialu_reg_mem);
6436 %}
6437
6438 // Load Unsigned Byte (8 bit UNsigned) into Long Register
6439 instruct loadUB2L(eRegL dst, memory mem)
6440 %{
6441 match(Set dst (ConvI2L (LoadUB mem)));
6442
6443 ins_cost(250);
6444 format %{ "MOVZX8 $dst.lo,$mem\t# ubyte -> long\n\t"
6445 "XOR $dst.hi,$dst.hi" %}
6446
6447 ins_encode %{
6448 __ movzbl($dst$$Register, $mem$$Address);
6449 __ xorl(HIGH_FROM_LOW($dst$$Register), HIGH_FROM_LOW($dst$$Register));
6450 %}
6451
6452 ins_pipe(ialu_reg_mem);
6453 %}
6454
6455 // Load Short (16bit signed)
6456 instruct loadS(eRegI dst, memory mem) %{
6457 match(Set dst (LoadS mem));
6458
6459 ins_cost(125);
6460 format %{ "MOVSX $dst,$mem\t# short" %}
6461
6462 ins_encode %{
6463 __ movswl($dst$$Register, $mem$$Address);
6464 %}
6465
6466 ins_pipe(ialu_reg_mem);
6467 %}
6468
6469 // Load Short (16bit signed) into Long Register
6470 instruct loadS2L(eRegL dst, memory mem) %{
6471 match(Set dst (ConvI2L (LoadS mem)));
6472
6473 ins_cost(375);
6474 format %{ "MOVSX $dst.lo,$mem\t# short -> long\n\t"
6475 "MOV $dst.hi,$dst.lo\n\t"
6476 "SAR $dst.hi,15" %}
6477
6478 ins_encode %{
6479 __ movswl($dst$$Register, $mem$$Address);
6480 __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register.
6481 __ sarl(HIGH_FROM_LOW($dst$$Register), 15); // 16+1 MSB are already signed extended.
6482 %}
6483
6484 ins_pipe(ialu_reg_mem);
6414 %} 6485 %}
6415 6486
6416 // Load Unsigned Short/Char (16bit unsigned) 6487 // Load Unsigned Short/Char (16bit unsigned)
6417 instruct loadUS(eRegI dst, memory mem) %{ 6488 instruct loadUS(eRegI dst, memory mem) %{
6418 match(Set dst (LoadUS mem)); 6489 match(Set dst (LoadUS mem));
6419 6490
6420 ins_cost(125); 6491 ins_cost(125);
6421 format %{ "MOVZX $dst,$mem" %} 6492 format %{ "MOVZX $dst,$mem\t# ushort/char -> int" %}
6422 opcode(0xB7, 0x0F); 6493
6423 ins_encode( OpcS, OpcP, RegMem(dst,mem)); 6494 ins_encode %{
6424 ins_pipe( ialu_reg_mem ); 6495 __ movzwl($dst$$Register, $mem$$Address);
6496 %}
6497
6498 ins_pipe(ialu_reg_mem);
6499 %}
6500
6501 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register
6502 instruct loadUS2L(eRegL dst, memory mem)
6503 %{
6504 match(Set dst (ConvI2L (LoadUS mem)));
6505
6506 ins_cost(250);
6507 format %{ "MOVZX $dst.lo,$mem\t# ushort/char -> long\n\t"
6508 "XOR $dst.hi,$dst.hi" %}
6509
6510 ins_encode %{
6511 __ movzwl($dst$$Register, $mem$$Address);
6512 __ xorl(HIGH_FROM_LOW($dst$$Register), HIGH_FROM_LOW($dst$$Register));
6513 %}
6514
6515 ins_pipe(ialu_reg_mem);
6425 %} 6516 %}
6426 6517
6427 // Load Integer 6518 // Load Integer
6428 instruct loadI(eRegI dst, memory mem) %{ 6519 instruct loadI(eRegI dst, memory mem) %{
6429 match(Set dst (LoadI mem)); 6520 match(Set dst (LoadI mem));
6430 6521
6431 ins_cost(125); 6522 ins_cost(125);
6432 format %{ "MOV $dst,$mem" %} 6523 format %{ "MOV $dst,$mem\t# int" %}
6433 opcode(0x8B); 6524
6434 ins_encode( OpcP, RegMem(dst,mem)); 6525 ins_encode %{
6435 ins_pipe( ialu_reg_mem ); 6526 __ movl($dst$$Register, $mem$$Address);
6527 %}
6528
6529 ins_pipe(ialu_reg_mem);
6530 %}
6531
6532 // Load Integer into Long Register
6533 instruct loadI2L(eRegL dst, memory mem) %{
6534 match(Set dst (ConvI2L (LoadI mem)));
6535
6536 ins_cost(375);
6537 format %{ "MOV $dst.lo,$mem\t# int -> long\n\t"
6538 "MOV $dst.hi,$dst.lo\n\t"
6539 "SAR $dst.hi,31" %}
6540
6541 ins_encode %{
6542 __ movl($dst$$Register, $mem$$Address);
6543 __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register.
6544 __ sarl(HIGH_FROM_LOW($dst$$Register), 31);
6545 %}
6546
6547 ins_pipe(ialu_reg_mem);
6548 %}
6549
6550 // Load Unsigned Integer into Long Register
6551 instruct loadUI2L(eRegL dst, memory mem) %{
6552 match(Set dst (LoadUI2L mem));
6553
6554 ins_cost(250);
6555 format %{ "MOV $dst.lo,$mem\t# uint -> long\n\t"
6556 "XOR $dst.hi,$dst.hi" %}
6557
6558 ins_encode %{
6559 __ movl($dst$$Register, $mem$$Address);
6560 __ xorl(HIGH_FROM_LOW($dst$$Register), HIGH_FROM_LOW($dst$$Register));
6561 %}
6562
6563 ins_pipe(ialu_reg_mem);
6436 %} 6564 %}
6437 6565
6438 // Load Long. Cannot clobber address while loading, so restrict address 6566 // Load Long. Cannot clobber address while loading, so restrict address
6439 // register to ESI 6567 // register to ESI
6440 instruct loadL(eRegL dst, load_long_memory mem) %{ 6568 instruct loadL(eRegL dst, load_long_memory mem) %{
6441 predicate(!((LoadLNode*)n)->require_atomic_access()); 6569 predicate(!((LoadLNode*)n)->require_atomic_access());
6442 match(Set dst (LoadL mem)); 6570 match(Set dst (LoadL mem));
6443 6571
6444 ins_cost(250); 6572 ins_cost(250);
6445 format %{ "MOV $dst.lo,$mem\n\t" 6573 format %{ "MOV $dst.lo,$mem\t# long\n\t"
6446 "MOV $dst.hi,$mem+4" %} 6574 "MOV $dst.hi,$mem+4" %}
6447 opcode(0x8B, 0x8B); 6575
6448 ins_encode( OpcP, RegMem(dst,mem), OpcS, RegMem_Hi(dst,mem)); 6576 ins_encode %{
6449 ins_pipe( ialu_reg_long_mem ); 6577 Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, false);
6578 Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, false);
6579 __ movl($dst$$Register, Amemlo);
6580 __ movl(HIGH_FROM_LOW($dst$$Register), Amemhi);
6581 %}
6582
6583 ins_pipe(ialu_reg_long_mem);
6450 %} 6584 %}
6451 6585
6452 // Volatile Load Long. Must be atomic, so do 64-bit FILD 6586 // Volatile Load Long. Must be atomic, so do 64-bit FILD
6453 // then store it down to the stack and reload on the int 6587 // then store it down to the stack and reload on the int
6454 // side. 6588 // side.
6516 6650
6517 ins_cost(125); 6651 ins_cost(125);
6518 format %{ "MOV $dst,$mem" %} 6652 format %{ "MOV $dst,$mem" %}
6519 opcode(0x8B); 6653 opcode(0x8B);
6520 ins_encode( OpcP, RegMem(dst,mem)); 6654 ins_encode( OpcP, RegMem(dst,mem));
6521 ins_pipe( ialu_reg_mem );
6522 %}
6523
6524 // Load Short (16bit signed)
6525 instruct loadS(eRegI dst, memory mem) %{
6526 match(Set dst (LoadS mem));
6527
6528 ins_cost(125);
6529 format %{ "MOVSX $dst,$mem" %}
6530 opcode(0xBF, 0x0F);
6531 ins_encode( OpcS, OpcP, RegMem(dst,mem));
6532 ins_pipe( ialu_reg_mem ); 6655 ins_pipe( ialu_reg_mem );
6533 %} 6656 %}
6534 6657
6535 // Load Double 6658 // Load Double
6536 instruct loadD(regD dst, memory mem) %{ 6659 instruct loadD(regD dst, memory mem) %{
7955 // rcx as the high order word of the new value to store but 8078 // rcx as the high order word of the new value to store but
7956 // our register encoding uses rbx. 8079 // our register encoding uses rbx.
7957 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc)); 8080 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
7958 if( os::is_MP() ) 8081 if( os::is_MP() )
7959 __ lock(); 8082 __ lock();
7960 __ cmpxchg8(Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp)); 8083 __ cmpxchg8($mem$$Address);
7961 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc)); 8084 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
7962 %} 8085 %}
7963 ins_pipe( pipe_cmpxchg ); 8086 ins_pipe( pipe_cmpxchg );
7964 %} 8087 %}
7965 8088
11465 %} 11588 %}
11466 11589
11467 instruct convI2L_reg( eRegL dst, eRegI src, eFlagsReg cr) %{ 11590 instruct convI2L_reg( eRegL dst, eRegI src, eFlagsReg cr) %{
11468 match(Set dst (ConvI2L src)); 11591 match(Set dst (ConvI2L src));
11469 effect(KILL cr); 11592 effect(KILL cr);
11593 ins_cost(375);
11470 format %{ "MOV $dst.lo,$src\n\t" 11594 format %{ "MOV $dst.lo,$src\n\t"
11471 "MOV $dst.hi,$src\n\t" 11595 "MOV $dst.hi,$src\n\t"
11472 "SAR $dst.hi,31" %} 11596 "SAR $dst.hi,31" %}
11473 ins_encode(convert_int_long(dst,src)); 11597 ins_encode(convert_int_long(dst,src));
11474 ins_pipe( ialu_reg_reg_long ); 11598 ins_pipe( ialu_reg_reg_long );
11476 11600
11477 // Zero-extend convert int to long 11601 // Zero-extend convert int to long
11478 instruct convI2L_reg_zex(eRegL dst, eRegI src, immL_32bits mask, eFlagsReg flags ) %{ 11602 instruct convI2L_reg_zex(eRegL dst, eRegI src, immL_32bits mask, eFlagsReg flags ) %{
11479 match(Set dst (AndL (ConvI2L src) mask) ); 11603 match(Set dst (AndL (ConvI2L src) mask) );
11480 effect( KILL flags ); 11604 effect( KILL flags );
11605 ins_cost(250);
11481 format %{ "MOV $dst.lo,$src\n\t" 11606 format %{ "MOV $dst.lo,$src\n\t"
11482 "XOR $dst.hi,$dst.hi" %} 11607 "XOR $dst.hi,$dst.hi" %}
11483 opcode(0x33); // XOR 11608 opcode(0x33); // XOR
11484 ins_encode(enc_Copy(dst,src), OpcP, RegReg_Hi2(dst,dst) ); 11609 ins_encode(enc_Copy(dst,src), OpcP, RegReg_Hi2(dst,dst) );
11485 ins_pipe( ialu_reg_reg_long ); 11610 ins_pipe( ialu_reg_reg_long );
11487 11612
11488 // Zero-extend long 11613 // Zero-extend long
11489 instruct zerox_long(eRegL dst, eRegL src, immL_32bits mask, eFlagsReg flags ) %{ 11614 instruct zerox_long(eRegL dst, eRegL src, immL_32bits mask, eFlagsReg flags ) %{
11490 match(Set dst (AndL src mask) ); 11615 match(Set dst (AndL src mask) );
11491 effect( KILL flags ); 11616 effect( KILL flags );
11617 ins_cost(250);
11492 format %{ "MOV $dst.lo,$src.lo\n\t" 11618 format %{ "MOV $dst.lo,$src.lo\n\t"
11493 "XOR $dst.hi,$dst.hi\n\t" %} 11619 "XOR $dst.hi,$dst.hi\n\t" %}
11494 opcode(0x33); // XOR 11620 opcode(0x33); // XOR
11495 ins_encode(enc_Copy(dst,src), OpcP, RegReg_Hi2(dst,dst) ); 11621 ins_encode(enc_Copy(dst,src), OpcP, RegReg_Hi2(dst,dst) );
11496 ins_pipe( ialu_reg_reg_long ); 11622 ins_pipe( ialu_reg_reg_long );