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
|