src/cpu/x86/vm/x86_64.ad

Print this page
rev 3419 : 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
Summary: use shorter instruction sequences for atomic add and atomic exchange when possible.
Reviewed-by:


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.


7234 %{
7235   match(Set cr (StoreLConditional mem (Binary oldval newval)));
7236   effect(KILL oldval);
7237 
7238   format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7239   opcode(0x0F, 0xB1);
7240   ins_encode(lock_prefix,
7241              REX_reg_mem_wide(newval, mem),
7242              OpcP, OpcS,
7243              reg_mem(newval, mem));
7244   ins_pipe(pipe_cmpxchg);
7245 %}
7246 
7247 
7248 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7249 instruct compareAndSwapP(rRegI res,
7250                          memory mem_ptr,
7251                          rax_RegP oldval, rRegP newval,
7252                          rFlagsReg cr)
7253 %{

7254   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
7255   effect(KILL cr, KILL oldval);
7256 
7257   format %{ "cmpxchgq $mem_ptr,$newval\t# "
7258             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7259             "sete    $res\n\t"
7260             "movzbl  $res, $res" %}
7261   opcode(0x0F, 0xB1);
7262   ins_encode(lock_prefix,
7263              REX_reg_mem_wide(newval, mem_ptr),
7264              OpcP, OpcS,
7265              reg_mem(newval, mem_ptr),
7266              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7267              REX_reg_breg(res, res), // movzbl
7268              Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7269   ins_pipe( pipe_cmpxchg );
7270 %}
7271 
7272 instruct compareAndSwapL(rRegI res,
7273                          memory mem_ptr,
7274                          rax_RegL oldval, rRegL newval,
7275                          rFlagsReg cr)
7276 %{

7277   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7278   effect(KILL cr, KILL oldval);
7279 
7280   format %{ "cmpxchgq $mem_ptr,$newval\t# "
7281             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7282             "sete    $res\n\t"
7283             "movzbl  $res, $res" %}
7284   opcode(0x0F, 0xB1);
7285   ins_encode(lock_prefix,
7286              REX_reg_mem_wide(newval, mem_ptr),
7287              OpcP, OpcS,
7288              reg_mem(newval, mem_ptr),
7289              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7290              REX_reg_breg(res, res), // movzbl
7291              Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7292   ins_pipe( pipe_cmpxchg );
7293 %}
7294 
7295 instruct compareAndSwapI(rRegI res,
7296                          memory mem_ptr,


7318 
7319 instruct compareAndSwapN(rRegI res,
7320                           memory mem_ptr,
7321                           rax_RegN oldval, rRegN newval,
7322                           rFlagsReg cr) %{
7323   match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
7324   effect(KILL cr, KILL oldval);
7325 
7326   format %{ "cmpxchgl $mem_ptr,$newval\t# "
7327             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7328             "sete    $res\n\t"
7329             "movzbl  $res, $res" %}
7330   opcode(0x0F, 0xB1);
7331   ins_encode(lock_prefix,
7332              REX_reg_mem(newval, mem_ptr),
7333              OpcP, OpcS,
7334              reg_mem(newval, mem_ptr),
7335              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7336              REX_reg_breg(res, res), // movzbl
7337              Opcode(0xF), Opcode(0xB6), reg_reg(res, res));


















































































7338   ins_pipe( pipe_cmpxchg );
7339 %}
7340 
7341 //----------Subtraction Instructions-------------------------------------------
7342 
7343 // Integer Subtraction Instructions
7344 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7345 %{
7346   match(Set dst (SubI dst src));
7347   effect(KILL cr);
7348 
7349   format %{ "subl    $dst, $src\t# int" %}
7350   opcode(0x2B);
7351   ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
7352   ins_pipe(ialu_reg_reg);
7353 %}
7354 
7355 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
7356 %{
7357   match(Set dst (SubI dst src));




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     case Op_CompareAndSwapL:
1527     case Op_CompareAndSwapP:
1528       if (!VM_Version::supports_cx8())
1529         return false;
1530     break;
1531   }
1532 
1533   return true;  // Per default match rules are supported.
1534 }
1535 
1536 int Matcher::regnum_to_fpu_offset(int regnum)
1537 {
1538   return regnum - 32; // The FP registers are in the second chunk
1539 }
1540 
1541 // This is UltraSparc specific, true just means we have fast l2f conversion
1542 const bool Matcher::convL2FSupported(void) {
1543   return true;
1544 }
1545 
1546 // Is this branch offset short enough that a short branch can be used?
1547 //
1548 // NOTE: If the platform does not provide any short branch variants, then
1549 //       this method should return false for offset 0.


7238 %{
7239   match(Set cr (StoreLConditional mem (Binary oldval newval)));
7240   effect(KILL oldval);
7241 
7242   format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7243   opcode(0x0F, 0xB1);
7244   ins_encode(lock_prefix,
7245              REX_reg_mem_wide(newval, mem),
7246              OpcP, OpcS,
7247              reg_mem(newval, mem));
7248   ins_pipe(pipe_cmpxchg);
7249 %}
7250 
7251 
7252 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7253 instruct compareAndSwapP(rRegI res,
7254                          memory mem_ptr,
7255                          rax_RegP oldval, rRegP newval,
7256                          rFlagsReg cr)
7257 %{
7258   predicate(VM_Version::supports_cx8());
7259   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
7260   effect(KILL cr, KILL oldval);
7261 
7262   format %{ "cmpxchgq $mem_ptr,$newval\t# "
7263             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7264             "sete    $res\n\t"
7265             "movzbl  $res, $res" %}
7266   opcode(0x0F, 0xB1);
7267   ins_encode(lock_prefix,
7268              REX_reg_mem_wide(newval, mem_ptr),
7269              OpcP, OpcS,
7270              reg_mem(newval, mem_ptr),
7271              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7272              REX_reg_breg(res, res), // movzbl
7273              Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7274   ins_pipe( pipe_cmpxchg );
7275 %}
7276 
7277 instruct compareAndSwapL(rRegI res,
7278                          memory mem_ptr,
7279                          rax_RegL oldval, rRegL newval,
7280                          rFlagsReg cr)
7281 %{
7282   predicate(VM_Version::supports_cx8());
7283   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7284   effect(KILL cr, KILL oldval);
7285 
7286   format %{ "cmpxchgq $mem_ptr,$newval\t# "
7287             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7288             "sete    $res\n\t"
7289             "movzbl  $res, $res" %}
7290   opcode(0x0F, 0xB1);
7291   ins_encode(lock_prefix,
7292              REX_reg_mem_wide(newval, mem_ptr),
7293              OpcP, OpcS,
7294              reg_mem(newval, mem_ptr),
7295              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7296              REX_reg_breg(res, res), // movzbl
7297              Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7298   ins_pipe( pipe_cmpxchg );
7299 %}
7300 
7301 instruct compareAndSwapI(rRegI res,
7302                          memory mem_ptr,


7324 
7325 instruct compareAndSwapN(rRegI res,
7326                           memory mem_ptr,
7327                           rax_RegN oldval, rRegN newval,
7328                           rFlagsReg cr) %{
7329   match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
7330   effect(KILL cr, KILL oldval);
7331 
7332   format %{ "cmpxchgl $mem_ptr,$newval\t# "
7333             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7334             "sete    $res\n\t"
7335             "movzbl  $res, $res" %}
7336   opcode(0x0F, 0xB1);
7337   ins_encode(lock_prefix,
7338              REX_reg_mem(newval, mem_ptr),
7339              OpcP, OpcS,
7340              reg_mem(newval, mem_ptr),
7341              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7342              REX_reg_breg(res, res), // movzbl
7343              Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7344   ins_pipe( pipe_cmpxchg );
7345 %}
7346 
7347 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
7348   predicate(n->as_LoadStore()->result_not_used());
7349   match(Set dummy (GetAndAddI mem add));
7350   effect(KILL cr);
7351   format %{ "ADDL  [$mem],$add" %}
7352   ins_encode %{
7353     if (os::is_MP()) { __ lock(); }
7354     __ addl($mem$$Address, $add$$constant);
7355   %}
7356   ins_pipe( pipe_cmpxchg );
7357 %}
7358 
7359 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{
7360   match(Set newval (GetAndAddI mem newval));
7361   effect(KILL cr);
7362   format %{ "XADDL  [$mem],$newval" %}
7363   ins_encode %{
7364     if (os::is_MP()) { __ lock(); }
7365     __ xaddl($mem$$Address, $newval$$Register);
7366   %}
7367   ins_pipe( pipe_cmpxchg );
7368 %}
7369 
7370 instruct xaddL_no_res( memory mem, Universe dummy, immL add, rFlagsReg cr) %{
7371   predicate(n->as_LoadStore()->result_not_used());
7372   match(Set dummy (GetAndAddL mem add));
7373   effect(KILL cr);
7374   format %{ "ADDQ  [$mem],$add" %}
7375   ins_encode %{
7376     if (os::is_MP()) { __ lock(); }
7377     __ addq($mem$$Address, $add$$constant);
7378   %}
7379   ins_pipe( pipe_cmpxchg );
7380 %}
7381 
7382 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{
7383   match(Set newval (GetAndAddL mem newval));
7384   effect(KILL cr);
7385   format %{ "XADDQ  [$mem],$newval" %}
7386   ins_encode %{
7387     if (os::is_MP()) { __ lock(); }
7388     __ xaddq($mem$$Address, $newval$$Register);
7389   %}
7390   ins_pipe( pipe_cmpxchg );
7391 %}
7392 
7393 instruct xchgI( memory mem, rRegI newval) %{
7394   match(Set newval (GetAndSetI mem newval));
7395   format %{ "XCHGL  $newval,[$mem]" %}
7396   ins_encode %{
7397     __ xchgl($newval$$Register, $mem$$Address);
7398   %}
7399   ins_pipe( pipe_cmpxchg );
7400 %}
7401 
7402 instruct xchgL( memory mem, rRegL newval) %{
7403   match(Set newval (GetAndSetL mem newval));
7404   format %{ "XCHGL  $newval,[$mem]" %}
7405   ins_encode %{
7406     __ xchgq($newval$$Register, $mem$$Address);
7407   %}
7408   ins_pipe( pipe_cmpxchg );
7409 %}
7410 
7411 instruct xchgP( memory mem, rRegP newval) %{
7412   match(Set newval (GetAndSetP mem newval));
7413   format %{ "XCHGQ  $newval,[$mem]" %}
7414   ins_encode %{
7415     __ xchgq($newval$$Register, $mem$$Address);
7416   %}
7417   ins_pipe( pipe_cmpxchg );
7418 %}
7419 
7420 instruct xchgN( memory mem, rRegN newval) %{
7421   match(Set newval (GetAndSetN mem newval));
7422   format %{ "XCHGL  $newval,$mem]" %}
7423   ins_encode %{
7424     __ xchgl($newval$$Register, $mem$$Address);
7425   %}
7426   ins_pipe( pipe_cmpxchg );
7427 %}
7428 
7429 //----------Subtraction Instructions-------------------------------------------
7430 
7431 // Integer Subtraction Instructions
7432 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7433 %{
7434   match(Set dst (SubI dst src));
7435   effect(KILL cr);
7436 
7437   format %{ "subl    $dst, $src\t# int" %}
7438   opcode(0x2B);
7439   ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
7440   ins_pipe(ialu_reg_reg);
7441 %}
7442 
7443 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
7444 %{
7445   match(Set dst (SubI dst src));