Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(247)

Side by Side Diff: src/mips/assembler-mips-inl.h

Issue 6709022: Re-establish mips basic infrastructure. (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Rebased on bleeding_edge r7374 Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/mips/assembler-mips.cc ('k') | src/mips/builtins-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 20 matching lines...) Expand all
31 // The original source code covered by the above license above has been 31 // The original source code covered by the above license above has been
32 // modified significantly by Google Inc. 32 // modified significantly by Google Inc.
33 // Copyright 2010 the V8 project authors. All rights reserved. 33 // Copyright 2010 the V8 project authors. All rights reserved.
34 34
35 35
36 #ifndef V8_MIPS_ASSEMBLER_MIPS_INL_H_ 36 #ifndef V8_MIPS_ASSEMBLER_MIPS_INL_H_
37 #define V8_MIPS_ASSEMBLER_MIPS_INL_H_ 37 #define V8_MIPS_ASSEMBLER_MIPS_INL_H_
38 38
39 #include "mips/assembler-mips.h" 39 #include "mips/assembler-mips.h"
40 #include "cpu.h" 40 #include "cpu.h"
41 #include "debug.h"
41 42
42 43
43 namespace v8 { 44 namespace v8 {
44 namespace internal { 45 namespace internal {
45 46
46 // ----------------------------------------------------------------------------- 47 // -----------------------------------------------------------------------------
47 // Condition
48
49 Condition NegateCondition(Condition cc) {
50 ASSERT(cc != cc_always);
51 return static_cast<Condition>(cc ^ 1);
52 }
53
54
55 // -----------------------------------------------------------------------------
56 // Operand and MemOperand 48 // Operand and MemOperand
57 49
58 Operand::Operand(int32_t immediate, RelocInfo::Mode rmode) { 50 Operand::Operand(int32_t immediate, RelocInfo::Mode rmode) {
59 rm_ = no_reg; 51 rm_ = no_reg;
60 imm32_ = immediate; 52 imm32_ = immediate;
61 rmode_ = rmode; 53 rmode_ = rmode;
62 } 54 }
63 55
56
64 Operand::Operand(const ExternalReference& f) { 57 Operand::Operand(const ExternalReference& f) {
65 rm_ = no_reg; 58 rm_ = no_reg;
66 imm32_ = reinterpret_cast<int32_t>(f.address()); 59 imm32_ = reinterpret_cast<int32_t>(f.address());
67 rmode_ = RelocInfo::EXTERNAL_REFERENCE; 60 rmode_ = RelocInfo::EXTERNAL_REFERENCE;
68 } 61 }
69 62
70 Operand::Operand(const char* s) {
71 rm_ = no_reg;
72 imm32_ = reinterpret_cast<int32_t>(s);
73 rmode_ = RelocInfo::EMBEDDED_STRING;
74 }
75 63
76 Operand::Operand(Smi* value) { 64 Operand::Operand(Smi* value) {
77 rm_ = no_reg; 65 rm_ = no_reg;
78 imm32_ = reinterpret_cast<intptr_t>(value); 66 imm32_ = reinterpret_cast<intptr_t>(value);
79 rmode_ = RelocInfo::NONE; 67 rmode_ = RelocInfo::NONE;
80 } 68 }
81 69
70
82 Operand::Operand(Register rm) { 71 Operand::Operand(Register rm) {
83 rm_ = rm; 72 rm_ = rm;
84 } 73 }
85 74
75
86 bool Operand::is_reg() const { 76 bool Operand::is_reg() const {
87 return rm_.is_valid(); 77 return rm_.is_valid();
88 } 78 }
89 79
90 80
91 81
92 // ----------------------------------------------------------------------------- 82 // -----------------------------------------------------------------------------
93 // RelocInfo 83 // RelocInfo
94 84
95 void RelocInfo::apply(intptr_t delta) { 85 void RelocInfo::apply(intptr_t delta) {
96 // On MIPS we do not use pc relative addressing, so we don't need to patch the 86 // On MIPS we do not use pc relative addressing, so we don't need to patch the
97 // code here. 87 // code here.
98 } 88 }
99 89
100 90
101 Address RelocInfo::target_address() { 91 Address RelocInfo::target_address() {
102 ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 92 ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
103 return Assembler::target_address_at(pc_); 93 return Assembler::target_address_at(pc_);
104 } 94 }
105 95
106 96
107 Address RelocInfo::target_address_address() { 97 Address RelocInfo::target_address_address() {
108 ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 98 ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY
109 return reinterpret_cast<Address>(pc_); 99 || rmode_ == EMBEDDED_OBJECT
100 || rmode_ == EXTERNAL_REFERENCE);
101 // Read the address of the word containing the target_address in an
102 // instruction stream.
103 // The only architecture-independent user of this function is the serializer.
104 // The serializer uses it to find out how many raw bytes of instruction to
105 // output before the next target.
106 // For an instructions like LUI/ORI where the target bits are mixed into the
107 // instruction bits, the size of the target will be zero, indicating that the
108 // serializer should not step forward in memory after a target is resolved
109 // and written. In this case the target_address_address function should
110 // return the end of the instructions to be patched, allowing the
111 // deserializer to deserialize the instructions as raw bytes and put them in
112 // place, ready to be patched with the target. In our case, that is the
113 // address of the instruction that follows LUI/ORI instruction pair.
114 return reinterpret_cast<Address>(
115 pc_ + Assembler::kInstructionsFor32BitConstant * Assembler::kInstrSize);
110 } 116 }
111 117
112 118
119 int RelocInfo::target_address_size() {
120 return Assembler::kExternalTargetSize;
121 }
122
123
113 void RelocInfo::set_target_address(Address target) { 124 void RelocInfo::set_target_address(Address target) {
114 ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 125 ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
115 Assembler::set_target_address_at(pc_, target); 126 Assembler::set_target_address_at(pc_, target);
116 } 127 }
117 128
118 129
119 Object* RelocInfo::target_object() { 130 Object* RelocInfo::target_object() {
120 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 131 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
121 return reinterpret_cast<Object*>(Assembler::target_address_at(pc_)); 132 return reinterpret_cast<Object*>(Assembler::target_address_at(pc_));
122 } 133 }
123 134
124 135
125 Handle<Object> RelocInfo::target_object_handle(Assembler *origin) { 136 Handle<Object> RelocInfo::target_object_handle(Assembler *origin) {
126 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 137 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
127 return Handle<Object>(reinterpret_cast<Object**>( 138 return Handle<Object>(reinterpret_cast<Object**>(
128 Assembler::target_address_at(pc_))); 139 Assembler::target_address_at(pc_)));
129 } 140 }
130 141
131 142
132 Object** RelocInfo::target_object_address() { 143 Object** RelocInfo::target_object_address() {
144 // Provide a "natural pointer" to the embedded object,
145 // which can be de-referenced during heap iteration.
133 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 146 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
134 return reinterpret_cast<Object**>(pc_); 147 // TODO(mips): Commenting out, to simplify arch-independent changes.
148 // GC won't work like this, but this commit is for asm/disasm/sim.
149 // reconstructed_obj_ptr_ =
150 // reinterpret_cast<Object*>(Assembler::target_address_at(pc_));
151 // return &reconstructed_obj_ptr_;
152 return NULL;
135 } 153 }
136 154
137 155
138 void RelocInfo::set_target_object(Object* target) { 156 void RelocInfo::set_target_object(Object* target) {
139 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 157 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
140 Assembler::set_target_address_at(pc_, reinterpret_cast<Address>(target)); 158 Assembler::set_target_address_at(pc_, reinterpret_cast<Address>(target));
141 } 159 }
142 160
143 161
144 Address* RelocInfo::target_reference_address() { 162 Address* RelocInfo::target_reference_address() {
145 ASSERT(rmode_ == EXTERNAL_REFERENCE); 163 ASSERT(rmode_ == EXTERNAL_REFERENCE);
146 return reinterpret_cast<Address*>(pc_); 164 // TODO(mips): Commenting out, to simplify arch-independent changes.
165 // GC won't work like this, but this commit is for asm/disasm/sim.
166 // reconstructed_adr_ptr_ = Assembler::target_address_at(pc_);
167 // return &reconstructed_adr_ptr_;
168 return NULL;
169 }
170
171
172 Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
173 ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
174 Address address = Memory::Address_at(pc_);
175 return Handle<JSGlobalPropertyCell>(
176 reinterpret_cast<JSGlobalPropertyCell**>(address));
177 }
178
179
180 JSGlobalPropertyCell* RelocInfo::target_cell() {
181 ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
182 Address address = Memory::Address_at(pc_);
183 Object* object = HeapObject::FromAddress(
184 address - JSGlobalPropertyCell::kValueOffset);
185 return reinterpret_cast<JSGlobalPropertyCell*>(object);
186 }
187
188
189 void RelocInfo::set_target_cell(JSGlobalPropertyCell* cell) {
190 ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
191 Address address = cell->address() + JSGlobalPropertyCell::kValueOffset;
192 Memory::Address_at(pc_) = address;
147 } 193 }
148 194
149 195
150 Address RelocInfo::call_address() { 196 Address RelocInfo::call_address() {
151 ASSERT(IsPatchedReturnSequence()); 197 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
152 // The 2 instructions offset assumes patched return sequence. 198 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
153 ASSERT(IsJSReturn(rmode())); 199 // The pc_ offset of 0 assumes mips patched return sequence per
154 return Memory::Address_at(pc_ + 2 * Assembler::kInstrSize); 200 // debug-mips.cc BreakLocationIterator::SetDebugBreakAtReturn(), or
201 // debug break slot per BreakLocationIterator::SetDebugBreakAtSlot().
202 return Assembler::target_address_at(pc_);
155 } 203 }
156 204
157 205
158 void RelocInfo::set_call_address(Address target) { 206 void RelocInfo::set_call_address(Address target) {
159 ASSERT(IsPatchedReturnSequence()); 207 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
160 // The 2 instructions offset assumes patched return sequence. 208 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
161 ASSERT(IsJSReturn(rmode())); 209 // The pc_ offset of 0 assumes mips patched return sequence per
162 Memory::Address_at(pc_ + 2 * Assembler::kInstrSize) = target; 210 // debug-mips.cc BreakLocationIterator::SetDebugBreakAtReturn(), or
211 // debug break slot per BreakLocationIterator::SetDebugBreakAtSlot().
212 Assembler::set_target_address_at(pc_, target);
163 } 213 }
164 214
165 215
166 Object* RelocInfo::call_object() { 216 Object* RelocInfo::call_object() {
167 return *call_object_address(); 217 return *call_object_address();
168 } 218 }
169 219
170 220
171 Object** RelocInfo::call_object_address() { 221 Object** RelocInfo::call_object_address() {
172 ASSERT(IsPatchedReturnSequence()); 222 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
173 // The 2 instructions offset assumes patched return sequence. 223 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
174 ASSERT(IsJSReturn(rmode()));
175 return reinterpret_cast<Object**>(pc_ + 2 * Assembler::kInstrSize); 224 return reinterpret_cast<Object**>(pc_ + 2 * Assembler::kInstrSize);
176 } 225 }
177 226
178 227
179 void RelocInfo::set_call_object(Object* target) { 228 void RelocInfo::set_call_object(Object* target) {
180 *call_object_address() = target; 229 *call_object_address() = target;
181 } 230 }
182 231
183 232
184 bool RelocInfo::IsPatchedReturnSequence() { 233 bool RelocInfo::IsPatchedReturnSequence() {
185 #ifdef DEBUG 234 Instr instr0 = Assembler::instr_at(pc_);
186 PrintF("%s - %d - %s : Checking for jal(r)", 235 Instr instr1 = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize);
187 __FILE__, __LINE__, __func__); 236 Instr instr2 = Assembler::instr_at(pc_ + 2 * Assembler::kInstrSize);
188 #endif 237 bool patched_return = ((instr0 & kOpcodeMask) == LUI &&
189 return ((Assembler::instr_at(pc_) & kOpcodeMask) == SPECIAL) && 238 (instr1 & kOpcodeMask) == ORI &&
190 (((Assembler::instr_at(pc_) & kFunctionFieldMask) == JAL) || 239 (instr2 & kOpcodeMask) == SPECIAL &&
191 ((Assembler::instr_at(pc_) & kFunctionFieldMask) == JALR)); 240 (instr2 & kFunctionFieldMask) == JALR);
241 return patched_return;
192 } 242 }
193 243
194 244
245 bool RelocInfo::IsPatchedDebugBreakSlotSequence() {
246 Instr current_instr = Assembler::instr_at(pc_);
247 return !Assembler::IsNop(current_instr, Assembler::DEBUG_BREAK_NOP);
248 }
249
250
251 void RelocInfo::Visit(ObjectVisitor* visitor) {
252 RelocInfo::Mode mode = rmode();
253 if (mode == RelocInfo::EMBEDDED_OBJECT) {
254 // RelocInfo is needed when pointer must be updated/serialized, such as
255 // UpdatingVisitor in mark-compact.cc or Serializer in serialize.cc.
256 // It is ignored by visitors that do not need it.
257 // Commenting out, to simplify arch-independednt changes.
258 // GC won't work like this, but this commit is for asm/disasm/sim.
259 // visitor->VisitPointer(target_object_address(), this);
260 } else if (RelocInfo::IsCodeTarget(mode)) {
261 visitor->VisitCodeTarget(this);
262 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
263 // RelocInfo is needed when external-references must be serialized by
264 // Serializer Visitor in serialize.cc. It is ignored by visitors that
265 // do not need it.
266 // Commenting out, to simplify arch-independednt changes.
267 // Serializer won't work like this, but this commit is for asm/disasm/sim.
268 // visitor->VisitExternalReference(target_reference_address(), this);
269 #ifdef ENABLE_DEBUGGER_SUPPORT
270 // TODO(isolates): Get a cached isolate below.
271 } else if (((RelocInfo::IsJSReturn(mode) &&
272 IsPatchedReturnSequence()) ||
273 (RelocInfo::IsDebugBreakSlot(mode) &&
274 IsPatchedDebugBreakSlotSequence())) &&
275 Isolate::Current()->debug()->has_break_points()) {
276 visitor->VisitDebugTarget(this);
277 #endif
278 } else if (mode == RelocInfo::RUNTIME_ENTRY) {
279 visitor->VisitRuntimeEntry(this);
280 }
281 }
282
283
284 template<typename StaticVisitor>
285 void RelocInfo::Visit(Heap* heap) {
286 RelocInfo::Mode mode = rmode();
287 if (mode == RelocInfo::EMBEDDED_OBJECT) {
288 StaticVisitor::VisitPointer(heap, target_object_address());
289 } else if (RelocInfo::IsCodeTarget(mode)) {
290 StaticVisitor::VisitCodeTarget(this);
291 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
292 StaticVisitor::VisitExternalReference(target_reference_address());
293 #ifdef ENABLE_DEBUGGER_SUPPORT
294 } else if (heap->isolate()->debug()->has_break_points() &&
295 ((RelocInfo::IsJSReturn(mode) &&
296 IsPatchedReturnSequence()) ||
297 (RelocInfo::IsDebugBreakSlot(mode) &&
298 IsPatchedDebugBreakSlotSequence()))) {
299 StaticVisitor::VisitDebugTarget(this);
300 #endif
301 } else if (mode == RelocInfo::RUNTIME_ENTRY) {
302 StaticVisitor::VisitRuntimeEntry(this);
303 }
304 }
305
306
195 // ----------------------------------------------------------------------------- 307 // -----------------------------------------------------------------------------
196 // Assembler 308 // Assembler
197 309
198 310
199 void Assembler::CheckBuffer() { 311 void Assembler::CheckBuffer() {
200 if (buffer_space() <= kGap) { 312 if (buffer_space() <= kGap) {
201 GrowBuffer(); 313 GrowBuffer();
202 } 314 }
203 } 315 }
204 316
205 317
318 void Assembler::CheckTrampolinePoolQuick() {
319 if (pc_offset() >= next_buffer_check_) {
320 CheckTrampolinePool();
321 }
322 }
323
324
206 void Assembler::emit(Instr x) { 325 void Assembler::emit(Instr x) {
207 CheckBuffer(); 326 CheckBuffer();
208 *reinterpret_cast<Instr*>(pc_) = x; 327 *reinterpret_cast<Instr*>(pc_) = x;
209 pc_ += kInstrSize; 328 pc_ += kInstrSize;
329 CheckTrampolinePoolQuick();
210 } 330 }
211 331
212 332
213 } } // namespace v8::internal 333 } } // namespace v8::internal
214 334
215 #endif // V8_MIPS_ASSEMBLER_MIPS_INL_H_ 335 #endif // V8_MIPS_ASSEMBLER_MIPS_INL_H_
OLDNEW
« no previous file with comments | « src/mips/assembler-mips.cc ('k') | src/mips/builtins-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698