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

src/cpu/x86/vm/x86_64.ad

Print this page




1496   address base =
1497   __ start_a_stub(size_deopt_handler());
1498   if (base == NULL)  return 0;  // CodeBuffer::expand failed
1499   int offset = __ offset();
1500   address the_pc = (address) __ pc();
1501   Label next;
1502   // push a "the_pc" on the stack without destroying any registers
1503   // as they all may be live.
1504 
1505   // push address of "next"
1506   __ call(next, relocInfo::none); // reloc none is fine since it is a disp32
1507   __ bind(next);
1508   // adjust it so it matches "the_pc"
1509   __ subptr(Address(rsp, 0), __ offset() - offset);
1510   __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
1511   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1512   __ end_a_stub();
1513   return offset;
1514 }
1515 
1516 
1517 const bool Matcher::match_rule_supported(int opcode) {
1518   if (!has_match_rule(opcode))
1519     return false;
1520 
1521   switch (opcode) {
1522     case Op_PopCountI:
1523     case Op_PopCountL:
1524       if (!UsePopCountInstruction)
1525         return false;
1526     break;
1527   }
1528 
1529   return true;  // Per default match rules are supported.
1530 }
1531 
1532 int Matcher::regnum_to_fpu_offset(int regnum)
1533 {
1534   return regnum - 32; // The FP registers are in the second chunk
1535 }
1536 
1537 // This is UltraSparc specific, true just means we have fast l2f conversion
1538 const bool Matcher::convL2FSupported(void) {
1539   return true;
1540 }
1541 
1542 // Is this branch offset short enough that a short branch can be used?
1543 //
1544 // NOTE: If the platform does not provide any short branch variants, then
1545 //       this method should return false for offset 0.
1546 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1547   // The passed offset is relative to address of the branch.
1548   // On 86 a branch displacement is calculated relative to address
1549   // of a next instruction.
1550   offset -= br_size;
1551 


10032   effect(DEF dst, USE src);
10033   ins_cost(85);
10034   format %{ "movd    $dst,$src\t# MoveF2I" %}
10035   ins_encode %{
10036     __ movdl($dst$$Register, $src$$XMMRegister);
10037   %}
10038   ins_pipe( pipe_slow );
10039 %}
10040 
10041 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{
10042   match(Set dst (MoveD2L src));
10043   effect(DEF dst, USE src);
10044   ins_cost(85);
10045   format %{ "movd    $dst,$src\t# MoveD2L" %}
10046   ins_encode %{
10047     __ movdq($dst$$Register, $src$$XMMRegister);
10048   %}
10049   ins_pipe( pipe_slow );
10050 %}
10051 
10052 // The next instructions have long latency and use Int unit. Set high cost.
10053 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{
10054   match(Set dst (MoveI2F src));
10055   effect(DEF dst, USE src);
10056   ins_cost(300);
10057   format %{ "movd    $dst,$src\t# MoveI2F" %}
10058   ins_encode %{
10059     __ movdl($dst$$XMMRegister, $src$$Register);
10060   %}
10061   ins_pipe( pipe_slow );
10062 %}
10063 
10064 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
10065   match(Set dst (MoveL2D src));
10066   effect(DEF dst, USE src);
10067   ins_cost(300);
10068   format %{ "movd    $dst,$src\t# MoveL2D" %}
10069   ins_encode %{
10070      __ movdq($dst$$XMMRegister, $src$$Register);
10071   %}
10072   ins_pipe( pipe_slow );
10073 %}
10074 
10075 
10076 // =======================================================================
10077 // fast clearing of an array
10078 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
10079                   rFlagsReg cr)
10080 %{
10081   match(Set dummy (ClearArray cnt base));
10082   effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
10083 
10084   format %{ "xorl    rax, rax\t# ClearArray:\n\t"
10085             "rep stosq\t# Store rax to *rdi++ while rcx--" %}
10086   ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax
10087              Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos




1496   address base =
1497   __ start_a_stub(size_deopt_handler());
1498   if (base == NULL)  return 0;  // CodeBuffer::expand failed
1499   int offset = __ offset();
1500   address the_pc = (address) __ pc();
1501   Label next;
1502   // push a "the_pc" on the stack without destroying any registers
1503   // as they all may be live.
1504 
1505   // push address of "next"
1506   __ call(next, relocInfo::none); // reloc none is fine since it is a disp32
1507   __ bind(next);
1508   // adjust it so it matches "the_pc"
1509   __ subptr(Address(rsp, 0), __ offset() - offset);
1510   __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
1511   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1512   __ end_a_stub();
1513   return offset;
1514 }
1515 
















1516 int Matcher::regnum_to_fpu_offset(int regnum)
1517 {
1518   return regnum - 32; // The FP registers are in the second chunk
1519 }
1520 
1521 // This is UltraSparc specific, true just means we have fast l2f conversion
1522 const bool Matcher::convL2FSupported(void) {
1523   return true;
1524 }
1525 
1526 // Is this branch offset short enough that a short branch can be used?
1527 //
1528 // NOTE: If the platform does not provide any short branch variants, then
1529 //       this method should return false for offset 0.
1530 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1531   // The passed offset is relative to address of the branch.
1532   // On 86 a branch displacement is calculated relative to address
1533   // of a next instruction.
1534   offset -= br_size;
1535 


10016   effect(DEF dst, USE src);
10017   ins_cost(85);
10018   format %{ "movd    $dst,$src\t# MoveF2I" %}
10019   ins_encode %{
10020     __ movdl($dst$$Register, $src$$XMMRegister);
10021   %}
10022   ins_pipe( pipe_slow );
10023 %}
10024 
10025 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{
10026   match(Set dst (MoveD2L src));
10027   effect(DEF dst, USE src);
10028   ins_cost(85);
10029   format %{ "movd    $dst,$src\t# MoveD2L" %}
10030   ins_encode %{
10031     __ movdq($dst$$Register, $src$$XMMRegister);
10032   %}
10033   ins_pipe( pipe_slow );
10034 %}
10035 

10036 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{
10037   match(Set dst (MoveI2F src));
10038   effect(DEF dst, USE src);
10039   ins_cost(100);
10040   format %{ "movd    $dst,$src\t# MoveI2F" %}
10041   ins_encode %{
10042     __ movdl($dst$$XMMRegister, $src$$Register);
10043   %}
10044   ins_pipe( pipe_slow );
10045 %}
10046 
10047 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
10048   match(Set dst (MoveL2D src));
10049   effect(DEF dst, USE src);
10050   ins_cost(100);
10051   format %{ "movd    $dst,$src\t# MoveL2D" %}
10052   ins_encode %{
10053      __ movdq($dst$$XMMRegister, $src$$Register);
10054   %}
10055   ins_pipe( pipe_slow );
10056 %}
10057 
10058 
10059 // =======================================================================
10060 // fast clearing of an array
10061 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
10062                   rFlagsReg cr)
10063 %{
10064   match(Set dummy (ClearArray cnt base));
10065   effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
10066 
10067   format %{ "xorl    rax, rax\t# ClearArray:\n\t"
10068             "rep stosq\t# Store rax to *rdi++ while rcx--" %}
10069   ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax
10070              Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos


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