__ movsd(Address(ESP, destination.GetStackIndex()), source.AsFpuRegister<XmmRegister>());
} else if (source.IsConstant()) {
HConstant* constant = source.GetConstant();
- int64_t value;
- if (constant->IsLongConstant()) {
- value = constant->AsLongConstant()->GetValue();
- } else {
- DCHECK(constant->IsDoubleConstant());
- value = bit_cast<int64_t, double>(constant->AsDoubleConstant()->GetValue());
- }
+ DCHECK(constant->IsLongConstant() || constant->IsDoubleConstant());
+ int64_t value = GetInt64ValueOf(constant);
__ movl(Address(ESP, destination.GetStackIndex()), Immediate(Low32Bits(value)));
- __ movl(Address(ESP, destination.GetHighStackIndex(kX86WordSize)), Immediate(High32Bits(value)));
+ __ movl(Address(ESP, destination.GetHighStackIndex(kX86WordSize)),
+ Immediate(High32Bits(value)));
} else {
DCHECK(source.IsDoubleStackSlot()) << source;
EmitParallelMoves(
Location lhs = condition->GetLocations()->InAt(0);
Location rhs = condition->GetLocations()->InAt(1);
// LHS is guaranteed to be in a register (see LocationsBuilderX86::HandleCondition).
- if (rhs.IsRegister()) {
- __ cmpl(lhs.AsRegister<Register>(), rhs.AsRegister<Register>());
- } else if (rhs.IsConstant()) {
- int32_t constant = CodeGenerator::GetInt32ValueOf(rhs.GetConstant());
- codegen_->Compare32BitValue(lhs.AsRegister<Register>(), constant);
- } else {
- __ cmpl(lhs.AsRegister<Register>(), Address(ESP, rhs.GetStackIndex()));
- }
+ codegen_->GenerateIntCompare(lhs, rhs);
if (true_target == nullptr) {
__ j(X86Condition(condition->GetOppositeCondition()), false_target);
} else {
locations->SetOut(Location::SameAsFirstInput());
}
-void CodeGeneratorX86::GenerateIntCompare(Location lhs, Location rhs) {
- Register lhs_reg = lhs.AsRegister<Register>();
- if (rhs.IsConstant()) {
- int32_t value = CodeGenerator::GetInt32ValueOf(rhs.GetConstant());
- Compare32BitValue(lhs_reg, value);
- } else if (rhs.IsStackSlot()) {
- assembler_.cmpl(lhs_reg, Address(ESP, rhs.GetStackIndex()));
- } else {
- assembler_.cmpl(lhs_reg, rhs.AsRegister<Register>());
- }
-}
-
void InstructionCodeGeneratorX86::VisitSelect(HSelect* select) {
LocationSummary* locations = select->GetLocations();
DCHECK(locations->InAt(0).Equals(locations->Out()));
} else {
DCHECK(value.IsConstant()) << value;
if (value.GetConstant()->AsIntConstant()->GetValue() == 0) {
- __ jmp(slow_path->GetEntryLabel());
+ __ jmp(slow_path->GetEntryLabel());
}
}
break;
switch (type) {
case Primitive::kPrimBoolean: {
Register out = out_loc.AsRegister<Register>();
- if (index.IsConstant()) {
- __ movzxb(out, Address(obj,
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset));
- } else {
- __ movzxb(out, Address(obj, index.AsRegister<Register>(), TIMES_1, data_offset));
- }
+ __ movzxb(out, CodeGeneratorX86::ArrayAddress(obj, index, TIMES_1, data_offset));
break;
}
case Primitive::kPrimByte: {
Register out = out_loc.AsRegister<Register>();
- if (index.IsConstant()) {
- __ movsxb(out, Address(obj,
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset));
- } else {
- __ movsxb(out, Address(obj, index.AsRegister<Register>(), TIMES_1, data_offset));
- }
+ __ movsxb(out, CodeGeneratorX86::ArrayAddress(obj, index, TIMES_1, data_offset));
break;
}
case Primitive::kPrimShort: {
Register out = out_loc.AsRegister<Register>();
- if (index.IsConstant()) {
- __ movsxw(out, Address(obj,
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset));
- } else {
- __ movsxw(out, Address(obj, index.AsRegister<Register>(), TIMES_2, data_offset));
- }
+ __ movsxw(out, CodeGeneratorX86::ArrayAddress(obj, index, TIMES_2, data_offset));
break;
}
case Primitive::kPrimChar: {
Register out = out_loc.AsRegister<Register>();
- if (index.IsConstant()) {
- __ movzxw(out, Address(obj,
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset));
- } else {
- __ movzxw(out, Address(obj, index.AsRegister<Register>(), TIMES_2, data_offset));
- }
+ __ movzxw(out, CodeGeneratorX86::ArrayAddress(obj, index, TIMES_2, data_offset));
break;
}
case Primitive::kPrimInt: {
Register out = out_loc.AsRegister<Register>();
- if (index.IsConstant()) {
- __ movl(out, Address(obj,
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset));
- } else {
- __ movl(out, Address(obj, index.AsRegister<Register>(), TIMES_4, data_offset));
- }
+ __ movl(out, CodeGeneratorX86::ArrayAddress(obj, index, TIMES_4, data_offset));
break;
}
instruction, out_loc, obj, data_offset, index, /* needs_null_check */ true);
} else {
Register out = out_loc.AsRegister<Register>();
+ __ movl(out, CodeGeneratorX86::ArrayAddress(obj, index, TIMES_4, data_offset));
+ codegen_->MaybeRecordImplicitNullCheck(instruction);
+ // If read barriers are enabled, emit read barriers other than
+ // Baker's using a slow path (and also unpoison the loaded
+ // reference, if heap poisoning is enabled).
if (index.IsConstant()) {
uint32_t offset =
(index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset;
- __ movl(out, Address(obj, offset));
- codegen_->MaybeRecordImplicitNullCheck(instruction);
- // If read barriers are enabled, emit read barriers other than
- // Baker's using a slow path (and also unpoison the loaded
- // reference, if heap poisoning is enabled).
codegen_->MaybeGenerateReadBarrierSlow(instruction, out_loc, out_loc, obj_loc, offset);
} else {
- __ movl(out, Address(obj, index.AsRegister<Register>(), TIMES_4, data_offset));
- codegen_->MaybeRecordImplicitNullCheck(instruction);
- // If read barriers are enabled, emit read barriers other than
- // Baker's using a slow path (and also unpoison the loaded
- // reference, if heap poisoning is enabled).
codegen_->MaybeGenerateReadBarrierSlow(
instruction, out_loc, out_loc, obj_loc, data_offset, index);
}
case Primitive::kPrimLong: {
DCHECK_NE(obj, out_loc.AsRegisterPairLow<Register>());
- if (index.IsConstant()) {
- size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset;
- __ movl(out_loc.AsRegisterPairLow<Register>(), Address(obj, offset));
- codegen_->MaybeRecordImplicitNullCheck(instruction);
- __ movl(out_loc.AsRegisterPairHigh<Register>(), Address(obj, offset + kX86WordSize));
- } else {
- __ movl(out_loc.AsRegisterPairLow<Register>(),
- Address(obj, index.AsRegister<Register>(), TIMES_8, data_offset));
- codegen_->MaybeRecordImplicitNullCheck(instruction);
- __ movl(out_loc.AsRegisterPairHigh<Register>(),
- Address(obj, index.AsRegister<Register>(), TIMES_8, data_offset + kX86WordSize));
- }
+ __ movl(out_loc.AsRegisterPairLow<Register>(),
+ CodeGeneratorX86::ArrayAddress(obj, index, TIMES_8, data_offset));
+ codegen_->MaybeRecordImplicitNullCheck(instruction);
+ __ movl(out_loc.AsRegisterPairHigh<Register>(),
+ CodeGeneratorX86::ArrayAddress(obj, index, TIMES_8, data_offset + kX86WordSize));
break;
}
case Primitive::kPrimFloat: {
XmmRegister out = out_loc.AsFpuRegister<XmmRegister>();
- if (index.IsConstant()) {
- __ movss(out, Address(obj,
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset));
- } else {
- __ movss(out, Address(obj, index.AsRegister<Register>(), TIMES_4, data_offset));
- }
+ __ movss(out, CodeGeneratorX86::ArrayAddress(obj, index, TIMES_4, data_offset));
break;
}
case Primitive::kPrimDouble: {
XmmRegister out = out_loc.AsFpuRegister<XmmRegister>();
- if (index.IsConstant()) {
- __ movsd(out, Address(obj,
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset));
- } else {
- __ movsd(out, Address(obj, index.AsRegister<Register>(), TIMES_8, data_offset));
- }
+ __ movsd(out, CodeGeneratorX86::ArrayAddress(obj, index, TIMES_8, data_offset));
break;
}
case Primitive::kPrimBoolean:
case Primitive::kPrimByte: {
uint32_t offset = mirror::Array::DataOffset(sizeof(uint8_t)).Uint32Value();
- Address address = index.IsConstant()
- ? Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + offset)
- : Address(array, index.AsRegister<Register>(), TIMES_1, offset);
+ Address address = CodeGeneratorX86::ArrayAddress(array, index, TIMES_1, offset);
if (value.IsRegister()) {
__ movb(address, value.AsRegister<ByteRegister>());
} else {
case Primitive::kPrimShort:
case Primitive::kPrimChar: {
uint32_t offset = mirror::Array::DataOffset(sizeof(uint16_t)).Uint32Value();
- Address address = index.IsConstant()
- ? Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + offset)
- : Address(array, index.AsRegister<Register>(), TIMES_2, offset);
+ Address address = CodeGeneratorX86::ArrayAddress(array, index, TIMES_2, offset);
if (value.IsRegister()) {
__ movw(address, value.AsRegister<Register>());
} else {
case Primitive::kPrimNot: {
uint32_t offset = mirror::Array::DataOffset(sizeof(int32_t)).Uint32Value();
- Address address = index.IsConstant()
- ? Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + offset)
- : Address(array, index.AsRegister<Register>(), TIMES_4, offset);
+ Address address = CodeGeneratorX86::ArrayAddress(array, index, TIMES_4, offset);
if (!value.IsRegister()) {
// Just setting null.
case Primitive::kPrimInt: {
uint32_t offset = mirror::Array::DataOffset(sizeof(int32_t)).Uint32Value();
- Address address = index.IsConstant()
- ? Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + offset)
- : Address(array, index.AsRegister<Register>(), TIMES_4, offset);
+ Address address = CodeGeneratorX86::ArrayAddress(array, index, TIMES_4, offset);
if (value.IsRegister()) {
__ movl(address, value.AsRegister<Register>());
} else {
case Primitive::kPrimLong: {
uint32_t data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Uint32Value();
- if (index.IsConstant()) {
- size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset;
- if (value.IsRegisterPair()) {
- __ movl(Address(array, offset), value.AsRegisterPairLow<Register>());
- codegen_->MaybeRecordImplicitNullCheck(instruction);
- __ movl(Address(array, offset + kX86WordSize), value.AsRegisterPairHigh<Register>());
- } else {
- DCHECK(value.IsConstant());
- int64_t val = value.GetConstant()->AsLongConstant()->GetValue();
- __ movl(Address(array, offset), Immediate(Low32Bits(val)));
- codegen_->MaybeRecordImplicitNullCheck(instruction);
- __ movl(Address(array, offset + kX86WordSize), Immediate(High32Bits(val)));
- }
+ if (value.IsRegisterPair()) {
+ __ movl(CodeGeneratorX86::ArrayAddress(array, index, TIMES_8, data_offset),
+ value.AsRegisterPairLow<Register>());
+ codegen_->MaybeRecordImplicitNullCheck(instruction);
+ __ movl(CodeGeneratorX86::ArrayAddress(array, index, TIMES_8, data_offset + kX86WordSize),
+ value.AsRegisterPairHigh<Register>());
} else {
- if (value.IsRegisterPair()) {
- __ movl(Address(array, index.AsRegister<Register>(), TIMES_8, data_offset),
- value.AsRegisterPairLow<Register>());
- codegen_->MaybeRecordImplicitNullCheck(instruction);
- __ movl(Address(array, index.AsRegister<Register>(), TIMES_8, data_offset + kX86WordSize),
- value.AsRegisterPairHigh<Register>());
- } else {
- DCHECK(value.IsConstant());
- int64_t val = value.GetConstant()->AsLongConstant()->GetValue();
- __ movl(Address(array, index.AsRegister<Register>(), TIMES_8, data_offset),
- Immediate(Low32Bits(val)));
- codegen_->MaybeRecordImplicitNullCheck(instruction);
- __ movl(Address(array, index.AsRegister<Register>(), TIMES_8, data_offset + kX86WordSize),
- Immediate(High32Bits(val)));
- }
+ DCHECK(value.IsConstant());
+ int64_t val = value.GetConstant()->AsLongConstant()->GetValue();
+ __ movl(CodeGeneratorX86::ArrayAddress(array, index, TIMES_8, data_offset),
+ Immediate(Low32Bits(val)));
+ codegen_->MaybeRecordImplicitNullCheck(instruction);
+ __ movl(CodeGeneratorX86::ArrayAddress(array, index, TIMES_8, data_offset + kX86WordSize),
+ Immediate(High32Bits(val)));
}
break;
}
case Primitive::kPrimFloat: {
uint32_t offset = mirror::Array::DataOffset(sizeof(float)).Uint32Value();
- Address address = index.IsConstant()
- ? Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + offset)
- : Address(array, index.AsRegister<Register>(), TIMES_4, offset);
+ Address address = CodeGeneratorX86::ArrayAddress(array, index, TIMES_4, offset);
if (value.IsFpuRegister()) {
__ movss(address, value.AsFpuRegister<XmmRegister>());
} else {
case Primitive::kPrimDouble: {
uint32_t offset = mirror::Array::DataOffset(sizeof(double)).Uint32Value();
- Address address = index.IsConstant()
- ? Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + offset)
- : Address(array, index.AsRegister<Register>(), TIMES_8, offset);
+ Address address = CodeGeneratorX86::ArrayAddress(array, index, TIMES_8, offset);
if (value.IsFpuRegister()) {
__ movsd(address, value.AsFpuRegister<XmmRegister>());
} else {
DCHECK(value.IsConstant());
- Address address_hi = index.IsConstant() ?
- Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) +
- offset + kX86WordSize) :
- Address(array, index.AsRegister<Register>(), TIMES_8, offset + kX86WordSize);
+ Address address_hi =
+ CodeGeneratorX86::ArrayAddress(array, index, TIMES_8, offset + kX86WordSize);
int64_t v = bit_cast<int64_t, double>(value.GetConstant()->AsDoubleConstant()->GetValue());
__ movl(address, Immediate(Low32Bits(v)));
codegen_->MaybeRecordImplicitNullCheck(instruction);
}
codegen_->MaybeRecordImplicitNullCheck(array_length);
} else {
- Register length = length_loc.AsRegister<Register>();
- if (index_loc.IsConstant()) {
- int32_t value = CodeGenerator::GetInt32ValueOf(index_loc.GetConstant());
- __ cmpl(length, Immediate(value));
- } else {
- __ cmpl(length, index_loc.AsRegister<Register>());
- }
+ codegen_->GenerateIntCompare(length_loc, index_loc);
}
codegen_->AddSlowPath(slow_path);
__ j(kBelowEqual, slow_path->GetEntryLabel());
"art::mirror::HeapReference<art::mirror::Object> and int32_t have different sizes.");
// /* HeapReference<Object> */ ref =
// *(obj + data_offset + index * sizeof(HeapReference<Object>))
- Address src = index.IsConstant() ?
- Address(obj, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset) :
- Address(obj, index.AsRegister<Register>(), TIMES_4, data_offset);
+ Address src = CodeGeneratorX86::ArrayAddress(obj, index, TIMES_4, data_offset);
GenerateReferenceLoadWithBakerReadBarrier(instruction, ref, obj, src, needs_null_check);
}
}
}
+void CodeGeneratorX86::GenerateIntCompare(Location lhs, Location rhs) {
+ Register lhs_reg = lhs.AsRegister<Register>();
+ if (rhs.IsConstant()) {
+ int32_t value = CodeGenerator::GetInt32ValueOf(rhs.GetConstant());
+ Compare32BitValue(lhs_reg, value);
+ } else if (rhs.IsStackSlot()) {
+ __ cmpl(lhs_reg, Address(ESP, rhs.GetStackIndex()));
+ } else {
+ __ cmpl(lhs_reg, rhs.AsRegister<Register>());
+ }
+}
+
+Address CodeGeneratorX86::ArrayAddress(Register obj,
+ Location index,
+ ScaleFactor scale,
+ uint32_t data_offset) {
+ return index.IsConstant() ?
+ Address(obj, (index.GetConstant()->AsIntConstant()->GetValue() << scale) + data_offset) :
+ Address(obj, index.AsRegister<Register>(), scale, data_offset);
+}
+
Address CodeGeneratorX86::LiteralCaseTable(HX86PackedSwitch* switch_instr,
Register reg,
Register value) {
source.AsFpuRegister<XmmRegister>());
} else if (source.IsConstant()) {
HConstant* constant = source.GetConstant();
- int64_t value;
- if (constant->IsDoubleConstant()) {
- value = bit_cast<int64_t, double>(constant->AsDoubleConstant()->GetValue());
- } else {
- DCHECK(constant->IsLongConstant());
- value = constant->AsLongConstant()->GetValue();
- }
+ DCHECK(constant->IsLongConstant() || constant->IsDoubleConstant());
+ int64_t value = GetInt64ValueOf(constant);
Store64BitValueToStack(destination, value);
} else {
DCHECK(source.IsDoubleStackSlot());
case Primitive::kPrimShort:
case Primitive::kPrimInt:
case Primitive::kPrimNot: {
- CpuRegister left_reg = left.AsRegister<CpuRegister>();
- if (right.IsConstant()) {
- int32_t value = CodeGenerator::GetInt32ValueOf(right.GetConstant());
- if (value == 0) {
- __ testl(left_reg, left_reg);
- } else {
- __ cmpl(left_reg, Immediate(value));
- }
- } else if (right.IsStackSlot()) {
- __ cmpl(left_reg, Address(CpuRegister(RSP), right.GetStackIndex()));
- } else {
- __ cmpl(left_reg, right.AsRegister<CpuRegister>());
- }
+ codegen_->GenerateIntCompare(left, right);
break;
}
case Primitive::kPrimLong: {
- CpuRegister left_reg = left.AsRegister<CpuRegister>();
- if (right.IsConstant()) {
- int64_t value = right.GetConstant()->AsLongConstant()->GetValue();
- codegen_->Compare64BitValue(left_reg, value);
- } else if (right.IsDoubleStackSlot()) {
- __ cmpq(left_reg, Address(CpuRegister(RSP), right.GetStackIndex()));
- } else {
- __ cmpq(left_reg, right.AsRegister<CpuRegister>());
- }
+ codegen_->GenerateLongCompare(left, right);
break;
}
case Primitive::kPrimFloat: {
Location lhs = condition->GetLocations()->InAt(0);
Location rhs = condition->GetLocations()->InAt(1);
- if (rhs.IsRegister()) {
- __ cmpl(lhs.AsRegister<CpuRegister>(), rhs.AsRegister<CpuRegister>());
- } else if (rhs.IsConstant()) {
- int32_t constant = CodeGenerator::GetInt32ValueOf(rhs.GetConstant());
- codegen_->Compare32BitValue(lhs.AsRegister<CpuRegister>(), constant);
- } else {
- __ cmpl(lhs.AsRegister<CpuRegister>(),
- Address(CpuRegister(RSP), rhs.GetStackIndex()));
- }
+ codegen_->GenerateIntCompare(lhs, rhs);
if (true_target == nullptr) {
__ j(X86_64IntegerCondition(condition->GetOppositeCondition()), false_target);
} else {
// Clear output register: setcc only sets the low byte.
__ xorl(reg, reg);
- if (rhs.IsRegister()) {
- __ cmpl(lhs.AsRegister<CpuRegister>(), rhs.AsRegister<CpuRegister>());
- } else if (rhs.IsConstant()) {
- int32_t constant = CodeGenerator::GetInt32ValueOf(rhs.GetConstant());
- codegen_->Compare32BitValue(lhs.AsRegister<CpuRegister>(), constant);
- } else {
- __ cmpl(lhs.AsRegister<CpuRegister>(), Address(CpuRegister(RSP), rhs.GetStackIndex()));
- }
+ codegen_->GenerateIntCompare(lhs, rhs);
__ setcc(X86_64IntegerCondition(cond->GetCondition()), reg);
return;
case Primitive::kPrimLong:
// Clear output register: setcc only sets the low byte.
__ xorl(reg, reg);
- if (rhs.IsRegister()) {
- __ cmpq(lhs.AsRegister<CpuRegister>(), rhs.AsRegister<CpuRegister>());
- } else if (rhs.IsConstant()) {
- int64_t value = rhs.GetConstant()->AsLongConstant()->GetValue();
- codegen_->Compare64BitValue(lhs.AsRegister<CpuRegister>(), value);
- } else {
- __ cmpq(lhs.AsRegister<CpuRegister>(), Address(CpuRegister(RSP), rhs.GetStackIndex()));
- }
+ codegen_->GenerateLongCompare(lhs, rhs);
__ setcc(X86_64IntegerCondition(cond->GetCondition()), reg);
return;
case Primitive::kPrimFloat: {
case Primitive::kPrimShort:
case Primitive::kPrimChar:
case Primitive::kPrimInt: {
- CpuRegister left_reg = left.AsRegister<CpuRegister>();
- if (right.IsConstant()) {
- int32_t value = right.GetConstant()->AsIntConstant()->GetValue();
- codegen_->Compare32BitValue(left_reg, value);
- } else if (right.IsStackSlot()) {
- __ cmpl(left_reg, Address(CpuRegister(RSP), right.GetStackIndex()));
- } else {
- __ cmpl(left_reg, right.AsRegister<CpuRegister>());
- }
+ codegen_->GenerateIntCompare(left, right);
break;
}
case Primitive::kPrimLong: {
- CpuRegister left_reg = left.AsRegister<CpuRegister>();
- if (right.IsConstant()) {
- int64_t value = right.GetConstant()->AsLongConstant()->GetValue();
- codegen_->Compare64BitValue(left_reg, value);
- } else if (right.IsDoubleStackSlot()) {
- __ cmpq(left_reg, Address(CpuRegister(RSP), right.GetStackIndex()));
- } else {
- __ cmpq(left_reg, right.AsRegister<CpuRegister>());
- }
+ codegen_->GenerateLongCompare(left, right);
break;
}
case Primitive::kPrimFloat: {
} else {
DCHECK(value.IsConstant()) << value;
if (value.GetConstant()->AsIntConstant()->GetValue() == 0) {
- __ jmp(slow_path->GetEntryLabel());
+ __ jmp(slow_path->GetEntryLabel());
}
}
break;
} else {
DCHECK(value.IsConstant()) << value;
if (value.GetConstant()->AsLongConstant()->GetValue() == 0) {
- __ jmp(slow_path->GetEntryLabel());
+ __ jmp(slow_path->GetEntryLabel());
}
}
break;
switch (type) {
case Primitive::kPrimBoolean: {
CpuRegister out = out_loc.AsRegister<CpuRegister>();
- if (index.IsConstant()) {
- __ movzxb(out, Address(obj,
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset));
- } else {
- __ movzxb(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_1, data_offset));
- }
+ __ movzxb(out, CodeGeneratorX86_64::ArrayAddress(obj, index, TIMES_1, data_offset));
break;
}
case Primitive::kPrimByte: {
CpuRegister out = out_loc.AsRegister<CpuRegister>();
- if (index.IsConstant()) {
- __ movsxb(out, Address(obj,
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset));
- } else {
- __ movsxb(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_1, data_offset));
- }
+ __ movsxb(out, CodeGeneratorX86_64::ArrayAddress(obj, index, TIMES_1, data_offset));
break;
}
case Primitive::kPrimShort: {
CpuRegister out = out_loc.AsRegister<CpuRegister>();
- if (index.IsConstant()) {
- __ movsxw(out, Address(obj,
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset));
- } else {
- __ movsxw(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_2, data_offset));
- }
+ __ movsxw(out, CodeGeneratorX86_64::ArrayAddress(obj, index, TIMES_2, data_offset));
break;
}
case Primitive::kPrimChar: {
CpuRegister out = out_loc.AsRegister<CpuRegister>();
- if (index.IsConstant()) {
- __ movzxw(out, Address(obj,
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset));
- } else {
- __ movzxw(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_2, data_offset));
- }
+ __ movzxw(out, CodeGeneratorX86_64::ArrayAddress(obj, index, TIMES_2, data_offset));
break;
}
case Primitive::kPrimInt: {
CpuRegister out = out_loc.AsRegister<CpuRegister>();
- if (index.IsConstant()) {
- __ movl(out, Address(obj,
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset));
- } else {
- __ movl(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_4, data_offset));
- }
+ __ movl(out, CodeGeneratorX86_64::ArrayAddress(obj, index, TIMES_4, data_offset));
break;
}
instruction, out_loc, obj, data_offset, index, /* needs_null_check */ true);
} else {
CpuRegister out = out_loc.AsRegister<CpuRegister>();
+ __ movl(out, CodeGeneratorX86_64::ArrayAddress(obj, index, TIMES_4, data_offset));
+ codegen_->MaybeRecordImplicitNullCheck(instruction);
+ // If read barriers are enabled, emit read barriers other than
+ // Baker's using a slow path (and also unpoison the loaded
+ // reference, if heap poisoning is enabled).
if (index.IsConstant()) {
uint32_t offset =
(index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset;
- __ movl(out, Address(obj, offset));
- codegen_->MaybeRecordImplicitNullCheck(instruction);
- // If read barriers are enabled, emit read barriers other than
- // Baker's using a slow path (and also unpoison the loaded
- // reference, if heap poisoning is enabled).
codegen_->MaybeGenerateReadBarrierSlow(instruction, out_loc, out_loc, obj_loc, offset);
} else {
- __ movl(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_4, data_offset));
- codegen_->MaybeRecordImplicitNullCheck(instruction);
- // If read barriers are enabled, emit read barriers other than
- // Baker's using a slow path (and also unpoison the loaded
- // reference, if heap poisoning is enabled).
codegen_->MaybeGenerateReadBarrierSlow(
instruction, out_loc, out_loc, obj_loc, data_offset, index);
}
case Primitive::kPrimLong: {
CpuRegister out = out_loc.AsRegister<CpuRegister>();
- if (index.IsConstant()) {
- __ movq(out, Address(obj,
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset));
- } else {
- __ movq(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_8, data_offset));
- }
+ __ movq(out, CodeGeneratorX86_64::ArrayAddress(obj, index, TIMES_8, data_offset));
break;
}
case Primitive::kPrimFloat: {
XmmRegister out = out_loc.AsFpuRegister<XmmRegister>();
- if (index.IsConstant()) {
- __ movss(out, Address(obj,
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset));
- } else {
- __ movss(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_4, data_offset));
- }
+ __ movss(out, CodeGeneratorX86_64::ArrayAddress(obj, index, TIMES_4, data_offset));
break;
}
case Primitive::kPrimDouble: {
XmmRegister out = out_loc.AsFpuRegister<XmmRegister>();
- if (index.IsConstant()) {
- __ movsd(out, Address(obj,
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset));
- } else {
- __ movsd(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_8, data_offset));
- }
+ __ movsd(out, CodeGeneratorX86_64::ArrayAddress(obj, index, TIMES_8, data_offset));
break;
}
case Primitive::kPrimBoolean:
case Primitive::kPrimByte: {
uint32_t offset = mirror::Array::DataOffset(sizeof(uint8_t)).Uint32Value();
- Address address = index.IsConstant()
- ? Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + offset)
- : Address(array, index.AsRegister<CpuRegister>(), TIMES_1, offset);
+ Address address = CodeGeneratorX86_64::ArrayAddress(array, index, TIMES_1, offset);
if (value.IsRegister()) {
__ movb(address, value.AsRegister<CpuRegister>());
} else {
case Primitive::kPrimShort:
case Primitive::kPrimChar: {
uint32_t offset = mirror::Array::DataOffset(sizeof(uint16_t)).Uint32Value();
- Address address = index.IsConstant()
- ? Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + offset)
- : Address(array, index.AsRegister<CpuRegister>(), TIMES_2, offset);
+ Address address = CodeGeneratorX86_64::ArrayAddress(array, index, TIMES_2, offset);
if (value.IsRegister()) {
__ movw(address, value.AsRegister<CpuRegister>());
} else {
case Primitive::kPrimNot: {
uint32_t offset = mirror::Array::DataOffset(sizeof(int32_t)).Uint32Value();
- Address address = index.IsConstant()
- ? Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + offset)
- : Address(array, index.AsRegister<CpuRegister>(), TIMES_4, offset);
+ Address address = CodeGeneratorX86_64::ArrayAddress(array, index, TIMES_4, offset);
if (!value.IsRegister()) {
// Just setting null.
case Primitive::kPrimInt: {
uint32_t offset = mirror::Array::DataOffset(sizeof(int32_t)).Uint32Value();
- Address address = index.IsConstant()
- ? Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + offset)
- : Address(array, index.AsRegister<CpuRegister>(), TIMES_4, offset);
+ Address address = CodeGeneratorX86_64::ArrayAddress(array, index, TIMES_4, offset);
if (value.IsRegister()) {
__ movl(address, value.AsRegister<CpuRegister>());
} else {
case Primitive::kPrimLong: {
uint32_t offset = mirror::Array::DataOffset(sizeof(int64_t)).Uint32Value();
- Address address = index.IsConstant()
- ? Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + offset)
- : Address(array, index.AsRegister<CpuRegister>(), TIMES_8, offset);
+ Address address = CodeGeneratorX86_64::ArrayAddress(array, index, TIMES_8, offset);
if (value.IsRegister()) {
__ movq(address, value.AsRegister<CpuRegister>());
codegen_->MaybeRecordImplicitNullCheck(instruction);
} else {
int64_t v = value.GetConstant()->AsLongConstant()->GetValue();
- Address address_high = index.IsConstant()
- ? Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) +
- offset + sizeof(int32_t))
- : Address(array, index.AsRegister<CpuRegister>(), TIMES_8, offset + sizeof(int32_t));
+ Address address_high =
+ CodeGeneratorX86_64::ArrayAddress(array, index, TIMES_8, offset + sizeof(int32_t));
codegen_->MoveInt64ToAddress(address, address_high, v, instruction);
}
break;
case Primitive::kPrimFloat: {
uint32_t offset = mirror::Array::DataOffset(sizeof(float)).Uint32Value();
- Address address = index.IsConstant()
- ? Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + offset)
- : Address(array, index.AsRegister<CpuRegister>(), TIMES_4, offset);
+ Address address = CodeGeneratorX86_64::ArrayAddress(array, index, TIMES_4, offset);
if (value.IsFpuRegister()) {
__ movss(address, value.AsFpuRegister<XmmRegister>());
} else {
DCHECK(value.IsConstant());
- int32_t v =
- bit_cast<int32_t, float>(value.GetConstant()->AsFloatConstant()->GetValue());
+ int32_t v = bit_cast<int32_t, float>(value.GetConstant()->AsFloatConstant()->GetValue());
__ movl(address, Immediate(v));
}
codegen_->MaybeRecordImplicitNullCheck(instruction);
case Primitive::kPrimDouble: {
uint32_t offset = mirror::Array::DataOffset(sizeof(double)).Uint32Value();
- Address address = index.IsConstant()
- ? Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + offset)
- : Address(array, index.AsRegister<CpuRegister>(), TIMES_8, offset);
+ Address address = CodeGeneratorX86_64::ArrayAddress(array, index, TIMES_8, offset);
if (value.IsFpuRegister()) {
__ movsd(address, value.AsFpuRegister<XmmRegister>());
codegen_->MaybeRecordImplicitNullCheck(instruction);
} else {
int64_t v =
bit_cast<int64_t, double>(value.GetConstant()->AsDoubleConstant()->GetValue());
- Address address_high = index.IsConstant()
- ? Address(array, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) +
- offset + sizeof(int32_t))
- : Address(array, index.AsRegister<CpuRegister>(), TIMES_8, offset + sizeof(int32_t));
+ Address address_high =
+ CodeGeneratorX86_64::ArrayAddress(array, index, TIMES_8, offset + sizeof(int32_t));
codegen_->MoveInt64ToAddress(address, address_high, v, instruction);
}
break;
}
codegen_->MaybeRecordImplicitNullCheck(array_length);
} else {
- CpuRegister length = length_loc.AsRegister<CpuRegister>();
- if (index_loc.IsConstant()) {
- int32_t value = CodeGenerator::GetInt32ValueOf(index_loc.GetConstant());
- __ cmpl(length, Immediate(value));
- } else {
- __ cmpl(length, index_loc.AsRegister<CpuRegister>());
- }
+ codegen_->GenerateIntCompare(length_loc, index_loc);
}
codegen_->AddSlowPath(slow_path);
__ j(kBelowEqual, slow_path->GetEntryLabel());
"art::mirror::HeapReference<art::mirror::Object> and int32_t have different sizes.");
// /* HeapReference<Object> */ ref =
// *(obj + data_offset + index * sizeof(HeapReference<Object>))
- Address src = index.IsConstant() ?
- Address(obj, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset) :
- Address(obj, index.AsRegister<CpuRegister>(), TIMES_4, data_offset);
+ Address src = CodeGeneratorX86_64::ArrayAddress(obj, index, TIMES_4, data_offset);
GenerateReferenceLoadWithBakerReadBarrier(instruction, ref, obj, src, needs_null_check);
}
}
}
+void CodeGeneratorX86_64::GenerateIntCompare(Location lhs, Location rhs) {
+ CpuRegister lhs_reg = lhs.AsRegister<CpuRegister>();
+ if (rhs.IsConstant()) {
+ int32_t value = CodeGenerator::GetInt32ValueOf(rhs.GetConstant());
+ Compare32BitValue(lhs_reg, value);
+ } else if (rhs.IsStackSlot()) {
+ __ cmpl(lhs_reg, Address(CpuRegister(RSP), rhs.GetStackIndex()));
+ } else {
+ __ cmpl(lhs_reg, rhs.AsRegister<CpuRegister>());
+ }
+}
+
+void CodeGeneratorX86_64::GenerateLongCompare(Location lhs, Location rhs) {
+ CpuRegister lhs_reg = lhs.AsRegister<CpuRegister>();
+ if (rhs.IsConstant()) {
+ int64_t value = rhs.GetConstant()->AsLongConstant()->GetValue();
+ Compare64BitValue(lhs_reg, value);
+ } else if (rhs.IsDoubleStackSlot()) {
+ __ cmpq(lhs_reg, Address(CpuRegister(RSP), rhs.GetStackIndex()));
+ } else {
+ __ cmpq(lhs_reg, rhs.AsRegister<CpuRegister>());
+ }
+}
+
+Address CodeGeneratorX86_64::ArrayAddress(CpuRegister obj,
+ Location index,
+ ScaleFactor scale,
+ uint32_t data_offset) {
+ return index.IsConstant() ?
+ Address(obj, (index.GetConstant()->AsIntConstant()->GetValue() << scale) + data_offset) :
+ Address(obj, index.AsRegister<CpuRegister>(), scale, data_offset);
+}
+
void CodeGeneratorX86_64::Store64BitValueToStack(Location dest, int64_t value) {
DCHECK(dest.IsDoubleStackSlot());
if (IsInt<32>(value)) {