src/cpu/sparc/vm/sparc.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:


1821 // Given a register encoding, produce a double-precision Float Register object
1822 static FloatRegister reg_to_DoubleFloatRegister_object(int register_encoding) {
1823   assert(F4->encoding(FloatRegisterImpl::D) == R_F4_enc, "right coding");
1824   assert(F32->encoding(FloatRegisterImpl::D) == R_D32_enc, "right coding");
1825   return as_DoubleFloatRegister(register_encoding);
1826 }
1827 
1828 const bool Matcher::match_rule_supported(int opcode) {
1829   if (!has_match_rule(opcode))
1830     return false;
1831 
1832   switch (opcode) {
1833   case Op_CountLeadingZerosI:
1834   case Op_CountLeadingZerosL:
1835   case Op_CountTrailingZerosI:
1836   case Op_CountTrailingZerosL:
1837   case Op_PopCountI:
1838   case Op_PopCountL:
1839     if (!UsePopCountInstruction)
1840       return false;






1841     break;
1842   }
1843 
1844   return true;  // Per default match rules are supported.
1845 }
1846 
1847 int Matcher::regnum_to_fpu_offset(int regnum) {
1848   return regnum - 32; // The FP registers are in the second chunk
1849 }
1850 
1851 #ifdef ASSERT
1852 address last_rethrow = NULL;  // debugging aid for Rethrow encoding
1853 #endif
1854 
1855 // Map Types to machine register types
1856 const int Matcher::base2reg[Type::lastype] = {
1857   Node::NotAMachineReg,0,0, Op_RegI, Op_RegL, 0, Op_RegN,
1858   Node::NotAMachineReg, Node::NotAMachineReg, /* tuple, array */
1859   0, Op_RegD, 0, 0, /* Vectors */
1860   Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, /* the pointers */


7197   effect( KILL newval );
7198   format %{ "CASA   [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
7199             "CMP    $oldval,$newval\t\t! See if we made progress"  %}
7200   ins_encode( enc_cas(mem_ptr,oldval,newval) );
7201   ins_pipe( long_memory_op );
7202 %}
7203 
7204 // Conditional-store of a long value.
7205 instruct storeLConditional( iRegP mem_ptr, iRegL oldval, g3RegL newval, flagsRegL xcc ) %{
7206   match(Set xcc (StoreLConditional mem_ptr (Binary oldval newval)));
7207   effect( KILL newval );
7208   format %{ "CASXA  [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
7209             "CMP    $oldval,$newval\t\t! See if we made progress"  %}
7210   ins_encode( enc_cas(mem_ptr,oldval,newval) );
7211   ins_pipe( long_memory_op );
7212 %}
7213 
7214 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7215 
7216 instruct compareAndSwapL_bool(iRegP mem_ptr, iRegL oldval, iRegL newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{

7217   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7218   effect( USE mem_ptr, KILL ccr, KILL tmp1);
7219   format %{
7220             "MOV    $newval,O7\n\t"
7221             "CASXA  [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t"
7222             "CMP    $oldval,O7\t\t! See if we made progress\n\t"
7223             "MOV    1,$res\n\t"
7224             "MOVne  xcc,R_G0,$res"
7225   %}
7226   ins_encode( enc_casx(mem_ptr, oldval, newval),
7227               enc_lflags_ne_to_boolean(res) );
7228   ins_pipe( long_memory_op );
7229 %}
7230 
7231 
7232 instruct compareAndSwapI_bool(iRegP mem_ptr, iRegI oldval, iRegI newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
7233   match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
7234   effect( USE mem_ptr, KILL ccr, KILL tmp1);
7235   format %{
7236             "MOV    $newval,O7\n\t"
7237             "CASA   [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t"
7238             "CMP    $oldval,O7\t\t! See if we made progress\n\t"
7239             "MOV    1,$res\n\t"
7240             "MOVne  icc,R_G0,$res"
7241   %}
7242   ins_encode( enc_casi(mem_ptr, oldval, newval),
7243               enc_iflags_ne_to_boolean(res) );
7244   ins_pipe( long_memory_op );
7245 %}
7246 
7247 instruct compareAndSwapP_bool(iRegP mem_ptr, iRegP oldval, iRegP newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{



7248   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
7249   effect( USE mem_ptr, KILL ccr, KILL tmp1);
7250   format %{
7251             "MOV    $newval,O7\n\t"
7252             "CASA_PTR  [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t"
7253             "CMP    $oldval,O7\t\t! See if we made progress\n\t"
7254             "MOV    1,$res\n\t"
7255             "MOVne  xcc,R_G0,$res"
7256   %}
7257 #ifdef _LP64
7258   ins_encode( enc_casx(mem_ptr, oldval, newval),
7259               enc_lflags_ne_to_boolean(res) );
7260 #else
7261   ins_encode( enc_casi(mem_ptr, oldval, newval),
7262               enc_iflags_ne_to_boolean(res) );
7263 #endif
7264   ins_pipe( long_memory_op );
7265 %}
7266 
7267 instruct compareAndSwapN_bool(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
7268   match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
7269   effect( USE mem_ptr, KILL ccr, KILL tmp1);
7270   format %{
7271             "MOV    $newval,O7\n\t"
7272             "CASA   [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t"
7273             "CMP    $oldval,O7\t\t! See if we made progress\n\t"
7274             "MOV    1,$res\n\t"
7275             "MOVne  icc,R_G0,$res"
7276   %}
7277   ins_encode( enc_casi(mem_ptr, oldval, newval),
7278               enc_iflags_ne_to_boolean(res) );
































7279   ins_pipe( long_memory_op );
7280 %}
7281 
7282 //---------------------
7283 // Subtraction Instructions
7284 // Register Subtraction
7285 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
7286   match(Set dst (SubI src1 src2));
7287 
7288   size(4);
7289   format %{ "SUB    $src1,$src2,$dst" %}
7290   opcode(Assembler::sub_op3, Assembler::arith_op);
7291   ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
7292   ins_pipe(ialu_reg_reg);
7293 %}
7294 
7295 // Immediate Subtraction
7296 instruct subI_reg_imm13(iRegI dst, iRegI src1, immI13 src2) %{
7297   match(Set dst (SubI src1 src2));
7298 




1821 // Given a register encoding, produce a double-precision Float Register object
1822 static FloatRegister reg_to_DoubleFloatRegister_object(int register_encoding) {
1823   assert(F4->encoding(FloatRegisterImpl::D) == R_F4_enc, "right coding");
1824   assert(F32->encoding(FloatRegisterImpl::D) == R_D32_enc, "right coding");
1825   return as_DoubleFloatRegister(register_encoding);
1826 }
1827 
1828 const bool Matcher::match_rule_supported(int opcode) {
1829   if (!has_match_rule(opcode))
1830     return false;
1831 
1832   switch (opcode) {
1833   case Op_CountLeadingZerosI:
1834   case Op_CountLeadingZerosL:
1835   case Op_CountTrailingZerosI:
1836   case Op_CountTrailingZerosL:
1837   case Op_PopCountI:
1838   case Op_PopCountL:
1839     if (!UsePopCountInstruction)
1840       return false;
1841   case Op_CompareAndSwapL:
1842 #ifdef _LP64
1843   case Op_CompareAndSwapP:
1844 #endif
1845     if (!VM_Version::supports_cx8())
1846       return false;
1847     break;
1848   }
1849 
1850   return true;  // Per default match rules are supported.
1851 }
1852 
1853 int Matcher::regnum_to_fpu_offset(int regnum) {
1854   return regnum - 32; // The FP registers are in the second chunk
1855 }
1856 
1857 #ifdef ASSERT
1858 address last_rethrow = NULL;  // debugging aid for Rethrow encoding
1859 #endif
1860 
1861 // Map Types to machine register types
1862 const int Matcher::base2reg[Type::lastype] = {
1863   Node::NotAMachineReg,0,0, Op_RegI, Op_RegL, 0, Op_RegN,
1864   Node::NotAMachineReg, Node::NotAMachineReg, /* tuple, array */
1865   0, Op_RegD, 0, 0, /* Vectors */
1866   Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, /* the pointers */


7203   effect( KILL newval );
7204   format %{ "CASA   [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
7205             "CMP    $oldval,$newval\t\t! See if we made progress"  %}
7206   ins_encode( enc_cas(mem_ptr,oldval,newval) );
7207   ins_pipe( long_memory_op );
7208 %}
7209 
7210 // Conditional-store of a long value.
7211 instruct storeLConditional( iRegP mem_ptr, iRegL oldval, g3RegL newval, flagsRegL xcc ) %{
7212   match(Set xcc (StoreLConditional mem_ptr (Binary oldval newval)));
7213   effect( KILL newval );
7214   format %{ "CASXA  [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
7215             "CMP    $oldval,$newval\t\t! See if we made progress"  %}
7216   ins_encode( enc_cas(mem_ptr,oldval,newval) );
7217   ins_pipe( long_memory_op );
7218 %}
7219 
7220 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7221 
7222 instruct compareAndSwapL_bool(iRegP mem_ptr, iRegL oldval, iRegL newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
7223   predicate(VM_Version::supports_cx8());
7224   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7225   effect( USE mem_ptr, KILL ccr, KILL tmp1);
7226   format %{
7227             "MOV    $newval,O7\n\t"
7228             "CASXA  [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t"
7229             "CMP    $oldval,O7\t\t! See if we made progress\n\t"
7230             "MOV    1,$res\n\t"
7231             "MOVne  xcc,R_G0,$res"
7232   %}
7233   ins_encode( enc_casx(mem_ptr, oldval, newval),
7234               enc_lflags_ne_to_boolean(res) );
7235   ins_pipe( long_memory_op );
7236 %}
7237 
7238 
7239 instruct compareAndSwapI_bool(iRegP mem_ptr, iRegI oldval, iRegI newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
7240   match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
7241   effect( USE mem_ptr, KILL ccr, KILL tmp1);
7242   format %{
7243             "MOV    $newval,O7\n\t"
7244             "CASA   [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t"
7245             "CMP    $oldval,O7\t\t! See if we made progress\n\t"
7246             "MOV    1,$res\n\t"
7247             "MOVne  icc,R_G0,$res"
7248   %}
7249   ins_encode( enc_casi(mem_ptr, oldval, newval),
7250               enc_iflags_ne_to_boolean(res) );
7251   ins_pipe( long_memory_op );
7252 %}
7253 
7254 instruct compareAndSwapP_bool(iRegP mem_ptr, iRegP oldval, iRegP newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
7255 #ifdef _LP64
7256   predicate(VM_Version::supports_cx8());
7257 #endif
7258   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
7259   effect( USE mem_ptr, KILL ccr, KILL tmp1);
7260   format %{
7261             "MOV    $newval,O7\n\t"
7262             "CASA_PTR  [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t"
7263             "CMP    $oldval,O7\t\t! See if we made progress\n\t"
7264             "MOV    1,$res\n\t"
7265             "MOVne  xcc,R_G0,$res"
7266   %}
7267 #ifdef _LP64
7268   ins_encode( enc_casx(mem_ptr, oldval, newval),
7269               enc_lflags_ne_to_boolean(res) );
7270 #else
7271   ins_encode( enc_casi(mem_ptr, oldval, newval),
7272               enc_iflags_ne_to_boolean(res) );
7273 #endif
7274   ins_pipe( long_memory_op );
7275 %}
7276 
7277 instruct compareAndSwapN_bool(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
7278   match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
7279   effect( USE mem_ptr, KILL ccr, KILL tmp1);
7280   format %{
7281             "MOV    $newval,O7\n\t"
7282             "CASA   [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t"
7283             "CMP    $oldval,O7\t\t! See if we made progress\n\t"
7284             "MOV    1,$res\n\t"
7285             "MOVne  icc,R_G0,$res"
7286   %}
7287   ins_encode( enc_casi(mem_ptr, oldval, newval),
7288               enc_iflags_ne_to_boolean(res) );
7289   ins_pipe( long_memory_op );
7290 %}
7291 
7292 instruct xchgI( memory mem, iRegI newval) %{
7293   match(Set newval (GetAndSetI mem newval));
7294   format %{ "SWAP  [$mem],$newval" %}
7295   size(4);
7296   ins_encode %{
7297     __ swap($mem$$Address, $newval$$Register);
7298   %}
7299   ins_pipe( long_memory_op );
7300 %}
7301 
7302 #ifndef _LP64
7303 instruct xchgP( memory mem, iRegP newval) %{
7304   match(Set newval (GetAndSetP mem newval));
7305   format %{ "SWAP  [$mem],$newval" %}
7306   size(4);
7307   ins_encode %{
7308     __ swap($mem$$Address, $newval$$Register);
7309   %}
7310   ins_pipe( long_memory_op );
7311 %}
7312 #endif
7313 
7314 instruct xchgN( memory mem, iRegN newval) %{
7315   match(Set newval (GetAndSetN mem newval));
7316   format %{ "SWAP  [$mem],$newval" %}
7317   size(4);
7318   ins_encode %{
7319     __ swap($mem$$Address, $newval$$Register);
7320   %}
7321   ins_pipe( long_memory_op );
7322 %}
7323 
7324 //---------------------
7325 // Subtraction Instructions
7326 // Register Subtraction
7327 instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
7328   match(Set dst (SubI src1 src2));
7329 
7330   size(4);
7331   format %{ "SUB    $src1,$src2,$dst" %}
7332   opcode(Assembler::sub_op3, Assembler::arith_op);
7333   ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
7334   ins_pipe(ialu_reg_reg);
7335 %}
7336 
7337 // Immediate Subtraction
7338 instruct subI_reg_imm13(iRegI dst, iRegI src1, immI13 src2) %{
7339   match(Set dst (SubI src1 src2));
7340