1376 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1377 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1378 emit_rm(cbuf, 0x1, reg & 7, 0x04);
1379 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1380 emit_d8(cbuf, offset);
1381 }
1382 }
1383
1384 uint BoxLockNode::size(PhaseRegAlloc *ra_) const
1385 {
1386 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1387 return (offset < 0x80) ? 5 : 8; // REX
1388 }
1389
1390 //=============================================================================
1391 #ifndef PRODUCT
1392 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1393 {
1394 if (UseCompressedKlassPointers) {
1395 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1396 if (Universe::narrow_klass_shift() != 0) {
1397 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
1398 }
1399 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
1400 } else {
1401 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
1402 "# Inline cache check");
1403 }
1404 st->print_cr("\tjne SharedRuntime::_ic_miss_stub");
1405 st->print_cr("\tnop\t# nops to align entry point");
1406 }
1407 #endif
1408
1409 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1410 {
1411 MacroAssembler masm(&cbuf);
1412 uint insts_size = cbuf.insts_size();
1413 if (UseCompressedKlassPointers) {
1414 masm.load_klass(rscratch1, j_rarg0);
1415 masm.cmpptr(rax, rscratch1);
1416 } else {
1417 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
1418 }
4018 %}
4019 %}
4020
4021 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
4022 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale)
4023 %{
4024 constraint(ALLOC_IN_RC(ptr_reg));
4025 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
4026 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off);
4027
4028 op_cost(10);
4029 format %{"[$reg + $off + $idx << $scale]" %}
4030 interface(MEMORY_INTER) %{
4031 base($reg);
4032 index($idx);
4033 scale($scale);
4034 disp($off);
4035 %}
4036 %}
4037
4038 operand indirectNarrowKlass(rRegN reg)
4039 %{
4040 predicate(Universe::narrow_klass_shift() == 0);
4041 constraint(ALLOC_IN_RC(ptr_reg));
4042 match(DecodeNKlass reg);
4043
4044 format %{ "[$reg]" %}
4045 interface(MEMORY_INTER) %{
4046 base($reg);
4047 index(0x4);
4048 scale(0x0);
4049 disp(0x0);
4050 %}
4051 %}
4052
4053 operand indOffset8NarrowKlass(rRegN reg, immL8 off)
4054 %{
4055 predicate(Universe::narrow_klass_shift() == 0);
4056 constraint(ALLOC_IN_RC(ptr_reg));
4057 match(AddP (DecodeNKlass reg) off);
4058
4059 format %{ "[$reg + $off (8-bit)]" %}
4060 interface(MEMORY_INTER) %{
4061 base($reg);
4062 index(0x4);
4063 scale(0x0);
4064 disp($off);
4065 %}
4066 %}
4067
4068 operand indOffset32NarrowKlass(rRegN reg, immL32 off)
4069 %{
4070 predicate(Universe::narrow_klass_shift() == 0);
4071 constraint(ALLOC_IN_RC(ptr_reg));
4072 match(AddP (DecodeNKlass reg) off);
4073
4074 format %{ "[$reg + $off (32-bit)]" %}
4075 interface(MEMORY_INTER) %{
4076 base($reg);
4077 index(0x4);
4078 scale(0x0);
4079 disp($off);
4080 %}
4081 %}
4082
4083 operand indIndexOffsetNarrowKlass(rRegN reg, rRegL lreg, immL32 off)
4084 %{
4085 predicate(Universe::narrow_klass_shift() == 0);
4086 constraint(ALLOC_IN_RC(ptr_reg));
4087 match(AddP (AddP (DecodeNKlass reg) lreg) off);
4088
4089 op_cost(10);
4090 format %{"[$reg + $off + $lreg]" %}
4091 interface(MEMORY_INTER) %{
4092 base($reg);
4093 index($lreg);
4094 scale(0x0);
4095 disp($off);
4096 %}
4097 %}
4098
4099 operand indIndexNarrowKlass(rRegN reg, rRegL lreg)
4100 %{
4101 predicate(Universe::narrow_klass_shift() == 0);
4102 constraint(ALLOC_IN_RC(ptr_reg));
4103 match(AddP (DecodeNKlass reg) lreg);
4104
4105 op_cost(10);
4106 format %{"[$reg + $lreg]" %}
4107 interface(MEMORY_INTER) %{
4108 base($reg);
4109 index($lreg);
4110 scale(0x0);
4111 disp(0x0);
4112 %}
4113 %}
4114
4115 operand indIndexScaleNarrowKlass(rRegN reg, rRegL lreg, immI2 scale)
4116 %{
4117 predicate(Universe::narrow_klass_shift() == 0);
4118 constraint(ALLOC_IN_RC(ptr_reg));
4119 match(AddP (DecodeNKlass reg) (LShiftL lreg scale));
4120
4121 op_cost(10);
4122 format %{"[$reg + $lreg << $scale]" %}
4123 interface(MEMORY_INTER) %{
4124 base($reg);
4125 index($lreg);
4126 scale($scale);
4127 disp(0x0);
4128 %}
4129 %}
4130
4131 operand indIndexScaleOffsetNarrowKlass(rRegN reg, immL32 off, rRegL lreg, immI2 scale)
4132 %{
4133 predicate(Universe::narrow_klass_shift() == 0);
4134 constraint(ALLOC_IN_RC(ptr_reg));
4135 match(AddP (AddP (DecodeNKlass reg) (LShiftL lreg scale)) off);
4136
4137 op_cost(10);
4138 format %{"[$reg + $off + $lreg << $scale]" %}
4139 interface(MEMORY_INTER) %{
4140 base($reg);
4141 index($lreg);
4142 scale($scale);
4143 disp($off);
4144 %}
4145 %}
4146
4147 operand indCompressedKlassOffset(rRegN reg, immL32 off) %{
4148 predicate(UseCompressedKlassPointers && (Universe::narrow_klass_shift() == Address::times_8));
4149 constraint(ALLOC_IN_RC(ptr_reg));
4150 match(AddP (DecodeNKlass reg) off);
4151
4152 op_cost(10);
4153 format %{"[R12 + $reg << 3 + $off] (compressed klass addressing)" %}
4154 interface(MEMORY_INTER) %{
4155 base(0xc); // R12
4156 index($reg);
4157 scale(0x3);
4158 disp($off);
4159 %}
4160 %}
4161
4162 operand indPosIndexScaleOffsetNarrowKlass(rRegN reg, immL32 off, rRegI idx, immI2 scale)
4163 %{
4164 constraint(ALLOC_IN_RC(ptr_reg));
4165 predicate(Universe::narrow_klass_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
4166 match(AddP (AddP (DecodeNKlass reg) (LShiftL (ConvI2L idx) scale)) off);
4167
4168 op_cost(10);
4169 format %{"[$reg + $off + $idx << $scale]" %}
4170 interface(MEMORY_INTER) %{
4171 base($reg);
4172 index($idx);
4173 scale($scale);
4174 disp($off);
4175 %}
4176 %}
4177
4178 //----------Special Memory Operands--------------------------------------------
4179 // Stack Slot Operand - This operand is used for loading and storing temporary
4180 // values on the stack where a match requires a value to
4181 // flow through memory.
4182 operand stackSlotP(sRegP reg)
4183 %{
4184 constraint(ALLOC_IN_RC(stack_slots));
4185 // No match rule because this operand is only generated in matching
4186
4187 format %{ "[$reg]" %}
4188 interface(MEMORY_INTER) %{
4189 base(0x4); // RSP
4190 index(0x4); // No Index
4191 scale(0x0); // No Scale
4192 disp($reg); // Stack Offset
4193 %}
4194 %}
4195
4196 operand stackSlotI(sRegI reg)
4197 %{
4328 less(0x2, "b");
4329 greater_equal(0x3, "nb");
4330 less_equal(0x6, "be");
4331 greater(0x7, "nbe");
4332 %}
4333 %}
4334
4335
4336 //----------OPERAND CLASSES----------------------------------------------------
4337 // Operand Classes are groups of operands that are used as to simplify
4338 // instruction definitions by not requiring the AD writer to specify separate
4339 // instructions for every form of operand when the instruction accepts
4340 // multiple operand types with the same basic encoding and format. The classic
4341 // case of this is memory operands.
4342
4343 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
4344 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
4345 indCompressedOopOffset,
4346 indirectNarrow, indOffset8Narrow, indOffset32Narrow,
4347 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
4348 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow,
4349 indCompressedKlassOffset,
4350 indirectNarrowKlass, indOffset8NarrowKlass, indOffset32NarrowKlass,
4351 indIndexOffsetNarrowKlass, indIndexNarrowKlass, indIndexScaleNarrowKlass,
4352 indIndexScaleOffsetNarrowKlass, indPosIndexScaleOffsetNarrowKlass);
4353
4354 //----------PIPELINE-----------------------------------------------------------
4355 // Rules which define the behavior of the target architectures pipeline.
4356 pipeline %{
4357
4358 //----------ATTRIBUTES---------------------------------------------------------
4359 attributes %{
4360 variable_size_instructions; // Fixed size instructions
4361 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle
4362 instruction_unit_size = 1; // An instruction is 1 bytes long
4363 instruction_fetch_unit_size = 16; // The processor fetches one line
4364 instruction_fetch_units = 1; // of 16 bytes
4365
4366 // List of nop instructions
4367 nops( MachNop );
4368 %}
4369
4370 //----------RESOURCES----------------------------------------------------------
4371 // Resources are the functional units available to the machine
4372
6648 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
6649 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
6650 match(Set dst (DecodeN src));
6651 effect(KILL cr);
6652 format %{ "decode_heap_oop_not_null $dst,$src" %}
6653 ins_encode %{
6654 Register s = $src$$Register;
6655 Register d = $dst$$Register;
6656 if (s != d) {
6657 __ decode_heap_oop_not_null(d, s);
6658 } else {
6659 __ decode_heap_oop_not_null(d);
6660 }
6661 %}
6662 ins_pipe(ialu_reg_long);
6663 %}
6664
6665 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6666 match(Set dst (EncodePKlass src));
6667 effect(KILL cr);
6668 format %{ "encode_heap_oop_not_null $dst,$src" %}
6669 ins_encode %{
6670 __ encode_klass_not_null($dst$$Register, $src$$Register);
6671 %}
6672 ins_pipe(ialu_reg_long);
6673 %}
6674
6675 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6676 match(Set dst (DecodeNKlass src));
6677 effect(KILL cr);
6678 format %{ "decode_heap_oop_not_null $dst,$src" %}
6679 ins_encode %{
6680 Register s = $src$$Register;
6681 Register d = $dst$$Register;
6682 if (s != d) {
6683 __ decode_klass_not_null(d, s);
6684 } else {
6685 __ decode_klass_not_null(d);
6686 }
6687 %}
6688 ins_pipe(ialu_reg_long);
6689 %}
6690
6691
6692 //----------Conditional Move---------------------------------------------------
6693 // Jump
6694 // dummy instruction for generating temp registers
6695 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
6696 match(Jump (LShiftL switch_val shift));
6697 ins_cost(350);
6698 predicate(false);
|
1376 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1377 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1378 emit_rm(cbuf, 0x1, reg & 7, 0x04);
1379 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1380 emit_d8(cbuf, offset);
1381 }
1382 }
1383
1384 uint BoxLockNode::size(PhaseRegAlloc *ra_) const
1385 {
1386 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1387 return (offset < 0x80) ? 5 : 8; // REX
1388 }
1389
1390 //=============================================================================
1391 #ifndef PRODUCT
1392 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1393 {
1394 if (UseCompressedKlassPointers) {
1395 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1396 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
1397 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
1398 } else {
1399 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
1400 "# Inline cache check");
1401 }
1402 st->print_cr("\tjne SharedRuntime::_ic_miss_stub");
1403 st->print_cr("\tnop\t# nops to align entry point");
1404 }
1405 #endif
1406
1407 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1408 {
1409 MacroAssembler masm(&cbuf);
1410 uint insts_size = cbuf.insts_size();
1411 if (UseCompressedKlassPointers) {
1412 masm.load_klass(rscratch1, j_rarg0);
1413 masm.cmpptr(rax, rscratch1);
1414 } else {
1415 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
1416 }
4016 %}
4017 %}
4018
4019 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
4020 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale)
4021 %{
4022 constraint(ALLOC_IN_RC(ptr_reg));
4023 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
4024 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off);
4025
4026 op_cost(10);
4027 format %{"[$reg + $off + $idx << $scale]" %}
4028 interface(MEMORY_INTER) %{
4029 base($reg);
4030 index($idx);
4031 scale($scale);
4032 disp($off);
4033 %}
4034 %}
4035
4036 //----------Special Memory Operands--------------------------------------------
4037 // Stack Slot Operand - This operand is used for loading and storing temporary
4038 // values on the stack where a match requires a value to
4039 // flow through memory.
4040 operand stackSlotP(sRegP reg)
4041 %{
4042 constraint(ALLOC_IN_RC(stack_slots));
4043 // No match rule because this operand is only generated in matching
4044
4045 format %{ "[$reg]" %}
4046 interface(MEMORY_INTER) %{
4047 base(0x4); // RSP
4048 index(0x4); // No Index
4049 scale(0x0); // No Scale
4050 disp($reg); // Stack Offset
4051 %}
4052 %}
4053
4054 operand stackSlotI(sRegI reg)
4055 %{
4186 less(0x2, "b");
4187 greater_equal(0x3, "nb");
4188 less_equal(0x6, "be");
4189 greater(0x7, "nbe");
4190 %}
4191 %}
4192
4193
4194 //----------OPERAND CLASSES----------------------------------------------------
4195 // Operand Classes are groups of operands that are used as to simplify
4196 // instruction definitions by not requiring the AD writer to specify separate
4197 // instructions for every form of operand when the instruction accepts
4198 // multiple operand types with the same basic encoding and format. The classic
4199 // case of this is memory operands.
4200
4201 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
4202 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
4203 indCompressedOopOffset,
4204 indirectNarrow, indOffset8Narrow, indOffset32Narrow,
4205 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
4206 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow);
4207
4208 //----------PIPELINE-----------------------------------------------------------
4209 // Rules which define the behavior of the target architectures pipeline.
4210 pipeline %{
4211
4212 //----------ATTRIBUTES---------------------------------------------------------
4213 attributes %{
4214 variable_size_instructions; // Fixed size instructions
4215 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle
4216 instruction_unit_size = 1; // An instruction is 1 bytes long
4217 instruction_fetch_unit_size = 16; // The processor fetches one line
4218 instruction_fetch_units = 1; // of 16 bytes
4219
4220 // List of nop instructions
4221 nops( MachNop );
4222 %}
4223
4224 //----------RESOURCES----------------------------------------------------------
4225 // Resources are the functional units available to the machine
4226
6502 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
6503 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
6504 match(Set dst (DecodeN src));
6505 effect(KILL cr);
6506 format %{ "decode_heap_oop_not_null $dst,$src" %}
6507 ins_encode %{
6508 Register s = $src$$Register;
6509 Register d = $dst$$Register;
6510 if (s != d) {
6511 __ decode_heap_oop_not_null(d, s);
6512 } else {
6513 __ decode_heap_oop_not_null(d);
6514 }
6515 %}
6516 ins_pipe(ialu_reg_long);
6517 %}
6518
6519 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6520 match(Set dst (EncodePKlass src));
6521 effect(KILL cr);
6522 format %{ "encode_klass_not_null $dst,$src" %}
6523 ins_encode %{
6524 __ encode_klass_not_null($dst$$Register, $src$$Register);
6525 %}
6526 ins_pipe(ialu_reg_long);
6527 %}
6528
6529 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6530 match(Set dst (DecodeNKlass src));
6531 effect(KILL cr);
6532 format %{ "decode_klass_not_null $dst,$src" %}
6533 ins_encode %{
6534 Register s = $src$$Register;
6535 Register d = $dst$$Register;
6536 if (s != d) {
6537 __ decode_klass_not_null(d, s);
6538 } else {
6539 __ decode_klass_not_null(d);
6540 }
6541 %}
6542 ins_pipe(ialu_reg_long);
6543 %}
6544
6545
6546 //----------Conditional Move---------------------------------------------------
6547 // Jump
6548 // dummy instruction for generating temp registers
6549 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
6550 match(Jump (LShiftL switch_val shift));
6551 ins_cost(350);
6552 predicate(false);
|