summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing/code_generator_x86.cc
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2014-03-11 17:53:17 +0000
committerNicolas Geoffray <ngeoffray@google.com>2014-03-13 09:23:12 +0000
commitbab4ed7057799a4fadc6283108ab56f389d117d4 (patch)
treeea1bf495458fd9f7a3ffbed0ea4e1dda5a0b8184 /compiler/optimizing/code_generator_x86.cc
parent37d4c1db4d705f5a28001f65afdd68d0527948d8 (diff)
downloadart-bab4ed7057799a4fadc6283108ab56f389d117d4.zip
art-bab4ed7057799a4fadc6283108ab56f389d117d4.tar.gz
art-bab4ed7057799a4fadc6283108ab56f389d117d4.tar.bz2
More code generation for the optimizing compiler.
- Add HReturn instruction - Generate code for locals/if/return - Setup infrastructure for register allocation. Currently emulate a stack. Change-Id: Ib28c2dba80f6c526177ed9a7b09c0689ac8122fb
Diffstat (limited to 'compiler/optimizing/code_generator_x86.cc')
-rw-r--r--compiler/optimizing/code_generator_x86.cc108
1 files changed, 99 insertions, 9 deletions
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index ab34599..81ada4d 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -26,6 +26,10 @@ namespace x86 {
void CodeGeneratorX86::GenerateFrameEntry() {
__ pushl(EBP);
__ movl(EBP, ESP);
+
+ if (frame_size_ != 0) {
+ __ subl(ESP, Immediate(frame_size_));
+ }
}
void CodeGeneratorX86::GenerateFrameExit() {
@@ -37,15 +41,36 @@ void CodeGeneratorX86::Bind(Label* label) {
__ Bind(label);
}
+void CodeGeneratorX86::Push(HInstruction* instruction, Location location) {
+ __ pushl(location.reg<Register>());
+}
+
+void CodeGeneratorX86::Move(HInstruction* instruction, Location location) {
+ HIntConstant* constant = instruction->AsIntConstant();
+ if (constant != nullptr) {
+ __ movl(location.reg<Register>(), Immediate(constant->value()));
+ } else {
+ __ popl(location.reg<Register>());
+ }
+}
+
+void LocationsBuilderX86::VisitGoto(HGoto* got) {
+ got->set_locations(nullptr);
+}
+
void CodeGeneratorX86::VisitGoto(HGoto* got) {
HBasicBlock* successor = got->GetSuccessor();
if (graph()->exit_block() == successor) {
GenerateFrameExit();
- } else if (!GoesToNextBlock(got)) {
+ } else if (!GoesToNextBlock(got->block(), successor)) {
__ jmp(GetLabelOf(successor));
}
}
+void LocationsBuilderX86::VisitExit(HExit* exit) {
+ exit->set_locations(nullptr);
+}
+
void CodeGeneratorX86::VisitExit(HExit* exit) {
if (kIsDebugBuild) {
__ Comment("Unreachable");
@@ -53,28 +78,81 @@ void CodeGeneratorX86::VisitExit(HExit* exit) {
}
}
+void LocationsBuilderX86::VisitIf(HIf* if_instr) {
+ LocationSummary* locations = new (graph()->arena()) LocationSummary(if_instr);
+ locations->SetInAt(0, Location(EAX));
+ if_instr->set_locations(locations);
+}
+
void CodeGeneratorX86::VisitIf(HIf* if_instr) {
- LOG(FATAL) << "UNIMPLEMENTED";
+ // TODO: Generate the input as a condition, instead of materializing in a register.
+ __ cmpl(if_instr->locations()->InAt(0).reg<Register>(), Immediate(0));
+ __ j(kEqual, GetLabelOf(if_instr->IfFalseSuccessor()));
+ if (!GoesToNextBlock(if_instr->block(), if_instr->IfTrueSuccessor())) {
+ __ jmp(GetLabelOf(if_instr->IfTrueSuccessor()));
+ }
+}
+
+void LocationsBuilderX86::VisitLocal(HLocal* local) {
+ local->set_locations(nullptr);
}
void CodeGeneratorX86::VisitLocal(HLocal* local) {
- LOG(FATAL) << "UNIMPLEMENTED";
+ DCHECK_EQ(local->block(), graph()->entry_block());
+ frame_size_ += kWordSize;
+}
+
+void LocationsBuilderX86::VisitLoadLocal(HLoadLocal* local) {
+ LocationSummary* locations = new (graph()->arena()) LocationSummary(local);
+ locations->SetOut(Location(EAX));
+ local->set_locations(locations);
+}
+
+static int32_t GetStackSlot(HLocal* local) {
+ // We are currently using EBP to access locals, so the offset must be negative.
+ return (local->reg_number() + 1) * -kWordSize;
+}
+
+void CodeGeneratorX86::VisitLoadLocal(HLoadLocal* load) {
+ __ movl(load->locations()->Out().reg<Register>(),
+ Address(EBP, GetStackSlot(load->GetLocal())));
}
-void CodeGeneratorX86::VisitLoadLocal(HLoadLocal* local) {
- LOG(FATAL) << "UNIMPLEMENTED";
+void LocationsBuilderX86::VisitStoreLocal(HStoreLocal* local) {
+ LocationSummary* locations = new (graph()->arena()) LocationSummary(local);
+ locations->SetInAt(1, Location(EAX));
+ local->set_locations(locations);
}
-void CodeGeneratorX86::VisitStoreLocal(HStoreLocal* local) {
- LOG(FATAL) << "UNIMPLEMENTED";
+void CodeGeneratorX86::VisitStoreLocal(HStoreLocal* store) {
+ __ movl(Address(EBP, GetStackSlot(store->GetLocal())),
+ store->locations()->InAt(1).reg<Register>());
+}
+
+void LocationsBuilderX86::VisitEqual(HEqual* equal) {
+ LocationSummary* locations = new (graph()->arena()) LocationSummary(equal);
+ locations->SetInAt(0, Location(EAX));
+ locations->SetInAt(1, Location(ECX));
+ locations->SetOut(Location(EAX));
+ equal->set_locations(locations);
}
void CodeGeneratorX86::VisitEqual(HEqual* equal) {
- LOG(FATAL) << "UNIMPLEMENTED";
+ __ cmpl(equal->locations()->InAt(0).reg<Register>(),
+ equal->locations()->InAt(1).reg<Register>());
+ __ setb(kEqual, equal->locations()->Out().reg<Register>());
+}
+
+void LocationsBuilderX86::VisitIntConstant(HIntConstant* constant) {
+ constant->set_locations(nullptr);
}
void CodeGeneratorX86::VisitIntConstant(HIntConstant* constant) {
- LOG(FATAL) << "UNIMPLEMENTED";
+ // Will be generated at use site.
+}
+
+void LocationsBuilderX86::VisitReturnVoid(HReturnVoid* ret) {
+ ret->set_locations(nullptr);
}
void CodeGeneratorX86::VisitReturnVoid(HReturnVoid* ret) {
@@ -82,5 +160,17 @@ void CodeGeneratorX86::VisitReturnVoid(HReturnVoid* ret) {
__ ret();
}
+void LocationsBuilderX86::VisitReturn(HReturn* ret) {
+ LocationSummary* locations = new (graph()->arena()) LocationSummary(ret);
+ locations->SetInAt(0, Location(EAX));
+ ret->set_locations(locations);
+}
+
+void CodeGeneratorX86::VisitReturn(HReturn* ret) {
+ DCHECK_EQ(ret->locations()->InAt(0).reg<Register>(), EAX);
+ GenerateFrameExit();
+ __ ret();
+}
+
} // namespace x86
} // namespace art