blob: 81ada4df6fffb1df163e6c570347196b140a86e0 [file] [log] [blame]
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +00001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "code_generator_x86.h"
18#include "utils/assembler.h"
19#include "utils/x86/assembler_x86.h"
20
21#define __ reinterpret_cast<X86Assembler*>(assembler())->
22
23namespace art {
24namespace x86 {
25
26void CodeGeneratorX86::GenerateFrameEntry() {
27 __ pushl(EBP);
28 __ movl(EBP, ESP);
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +000029
30 if (frame_size_ != 0) {
31 __ subl(ESP, Immediate(frame_size_));
32 }
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +000033}
34
35void CodeGeneratorX86::GenerateFrameExit() {
36 __ movl(ESP, EBP);
37 __ popl(EBP);
38}
39
40void CodeGeneratorX86::Bind(Label* label) {
41 __ Bind(label);
42}
43
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +000044void CodeGeneratorX86::Push(HInstruction* instruction, Location location) {
45 __ pushl(location.reg<Register>());
46}
47
48void CodeGeneratorX86::Move(HInstruction* instruction, Location location) {
49 HIntConstant* constant = instruction->AsIntConstant();
50 if (constant != nullptr) {
51 __ movl(location.reg<Register>(), Immediate(constant->value()));
52 } else {
53 __ popl(location.reg<Register>());
54 }
55}
56
57void LocationsBuilderX86::VisitGoto(HGoto* got) {
58 got->set_locations(nullptr);
59}
60
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +000061void CodeGeneratorX86::VisitGoto(HGoto* got) {
62 HBasicBlock* successor = got->GetSuccessor();
63 if (graph()->exit_block() == successor) {
64 GenerateFrameExit();
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +000065 } else if (!GoesToNextBlock(got->block(), successor)) {
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +000066 __ jmp(GetLabelOf(successor));
67 }
68}
69
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +000070void LocationsBuilderX86::VisitExit(HExit* exit) {
71 exit->set_locations(nullptr);
72}
73
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +000074void CodeGeneratorX86::VisitExit(HExit* exit) {
75 if (kIsDebugBuild) {
76 __ Comment("Unreachable");
77 __ int3();
78 }
79}
80
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +000081void LocationsBuilderX86::VisitIf(HIf* if_instr) {
82 LocationSummary* locations = new (graph()->arena()) LocationSummary(if_instr);
83 locations->SetInAt(0, Location(EAX));
84 if_instr->set_locations(locations);
85}
86
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +000087void CodeGeneratorX86::VisitIf(HIf* if_instr) {
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +000088 // TODO: Generate the input as a condition, instead of materializing in a register.
89 __ cmpl(if_instr->locations()->InAt(0).reg<Register>(), Immediate(0));
90 __ j(kEqual, GetLabelOf(if_instr->IfFalseSuccessor()));
91 if (!GoesToNextBlock(if_instr->block(), if_instr->IfTrueSuccessor())) {
92 __ jmp(GetLabelOf(if_instr->IfTrueSuccessor()));
93 }
94}
95
96void LocationsBuilderX86::VisitLocal(HLocal* local) {
97 local->set_locations(nullptr);
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +000098}
99
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000100void CodeGeneratorX86::VisitLocal(HLocal* local) {
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000101 DCHECK_EQ(local->block(), graph()->entry_block());
102 frame_size_ += kWordSize;
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000103}
104
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000105void LocationsBuilderX86::VisitLoadLocal(HLoadLocal* local) {
106 LocationSummary* locations = new (graph()->arena()) LocationSummary(local);
107 locations->SetOut(Location(EAX));
108 local->set_locations(locations);
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000109}
110
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000111static int32_t GetStackSlot(HLocal* local) {
112 // We are currently using EBP to access locals, so the offset must be negative.
113 return (local->reg_number() + 1) * -kWordSize;
114}
115
116void CodeGeneratorX86::VisitLoadLocal(HLoadLocal* load) {
117 __ movl(load->locations()->Out().reg<Register>(),
118 Address(EBP, GetStackSlot(load->GetLocal())));
119}
120
121void LocationsBuilderX86::VisitStoreLocal(HStoreLocal* local) {
122 LocationSummary* locations = new (graph()->arena()) LocationSummary(local);
123 locations->SetInAt(1, Location(EAX));
124 local->set_locations(locations);
125}
126
127void CodeGeneratorX86::VisitStoreLocal(HStoreLocal* store) {
128 __ movl(Address(EBP, GetStackSlot(store->GetLocal())),
129 store->locations()->InAt(1).reg<Register>());
130}
131
132void LocationsBuilderX86::VisitEqual(HEqual* equal) {
133 LocationSummary* locations = new (graph()->arena()) LocationSummary(equal);
134 locations->SetInAt(0, Location(EAX));
135 locations->SetInAt(1, Location(ECX));
136 locations->SetOut(Location(EAX));
137 equal->set_locations(locations);
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000138}
139
140void CodeGeneratorX86::VisitEqual(HEqual* equal) {
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000141 __ cmpl(equal->locations()->InAt(0).reg<Register>(),
142 equal->locations()->InAt(1).reg<Register>());
143 __ setb(kEqual, equal->locations()->Out().reg<Register>());
144}
145
146void LocationsBuilderX86::VisitIntConstant(HIntConstant* constant) {
147 constant->set_locations(nullptr);
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000148}
149
150void CodeGeneratorX86::VisitIntConstant(HIntConstant* constant) {
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000151 // Will be generated at use site.
152}
153
154void LocationsBuilderX86::VisitReturnVoid(HReturnVoid* ret) {
155 ret->set_locations(nullptr);
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000156}
157
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000158void CodeGeneratorX86::VisitReturnVoid(HReturnVoid* ret) {
159 GenerateFrameExit();
160 __ ret();
161}
162
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000163void LocationsBuilderX86::VisitReturn(HReturn* ret) {
164 LocationSummary* locations = new (graph()->arena()) LocationSummary(ret);
165 locations->SetInAt(0, Location(EAX));
166 ret->set_locations(locations);
167}
168
169void CodeGeneratorX86::VisitReturn(HReturn* ret) {
170 DCHECK_EQ(ret->locations()->InAt(0).reg<Register>(), EAX);
171 GenerateFrameExit();
172 __ ret();
173}
174
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000175} // namespace x86
176} // namespace art