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

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: Updated per comments, and rebased on r7312. Created 9 years, 9 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
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 // Commenting out, to simplify arch-independednt changes.
Søren Thygesen Gjesse 2011/03/23 23:38:42 I suggest adding a TODO(mips) to the beginning of
Paul Lind 2011/03/26 18:39:17 Done.
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 // Commenting out, to simplify arch-independednt changes.
Søren Thygesen Gjesse 2011/03/23 23:38:42 Ditto.
Paul Lind 2011/03/26 18:39:17 Done.
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
Søren Thygesen Gjesse 2011/03/23 23:38:42 patched return sequence -> patched return sequence
Paul Lind 2011/03/26 18:39:17 Done.
154 return Memory::Address_at(pc_ + 2 * Assembler::kInstrSize); 200 // debug-mips.cc BreakLocationIterator::SetDebugBreakAtReturn().
201 return Assembler::target_address_at(pc_);
155 } 202 }
156 203
157 204
158 void RelocInfo::set_call_address(Address target) { 205 void RelocInfo::set_call_address(Address target) {
159 ASSERT(IsPatchedReturnSequence()); 206 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
160 // The 2 instructions offset assumes patched return sequence. 207 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
161 ASSERT(IsJSReturn(rmode())); 208 // The pc_ offset of 0 assumes mips patched return sequence per
Søren Thygesen Gjesse 2011/03/23 23:38:42 Ditto.
Paul Lind 2011/03/26 18:39:17 Done.
162 Memory::Address_at(pc_ + 2 * Assembler::kInstrSize) = target; 209 // debug-mips.cc BreakLocationIterator::SetDebugBreakAtReturn().
210 Assembler::set_target_address_at(pc_, target);
163 } 211 }
164 212
165 213
166 Object* RelocInfo::call_object() { 214 Object* RelocInfo::call_object() {
167 return *call_object_address(); 215 return *call_object_address();
168 } 216 }
169 217
170 218
171 Object** RelocInfo::call_object_address() { 219 Object** RelocInfo::call_object_address() {
172 ASSERT(IsPatchedReturnSequence()); 220 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
173 // The 2 instructions offset assumes patched return sequence. 221 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
174 ASSERT(IsJSReturn(rmode()));
175 return reinterpret_cast<Object**>(pc_ + 2 * Assembler::kInstrSize); 222 return reinterpret_cast<Object**>(pc_ + 2 * Assembler::kInstrSize);
176 } 223 }
177 224
178 225
179 void RelocInfo::set_call_object(Object* target) { 226 void RelocInfo::set_call_object(Object* target) {
180 *call_object_address() = target; 227 *call_object_address() = target;
181 } 228 }
182 229
183 230
184 bool RelocInfo::IsPatchedReturnSequence() { 231 bool RelocInfo::IsPatchedReturnSequence() {
185 #ifdef DEBUG 232 Instr instr0 = Assembler::instr_at(pc_);
186 PrintF("%s - %d - %s : Checking for jal(r)", 233 Instr instr1 = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize);
187 __FILE__, __LINE__, __func__); 234 Instr instr2 = Assembler::instr_at(pc_ + 2 * Assembler::kInstrSize);
188 #endif 235 bool patched_return = ((instr0 & kOpcodeMask) == LUI &&
189 return ((Assembler::instr_at(pc_) & kOpcodeMask) == SPECIAL) && 236 (instr1 & kOpcodeMask) == ORI &&
190 (((Assembler::instr_at(pc_) & kFunctionFieldMask) == JAL) || 237 (instr2 & kOpcodeMask) == SPECIAL &&
191 ((Assembler::instr_at(pc_) & kFunctionFieldMask) == JALR)); 238 (instr2 & kFunctionFieldMask) == JALR);
239 return patched_return;
192 } 240 }
193 241
194 242
243 bool RelocInfo::IsPatchedDebugBreakSlotSequence() {
244 Instr current_instr = Assembler::instr_at(pc_);
245 return !Assembler::IsNop(current_instr, Assembler::DEBUG_BREAK_NOP);
246 }
247
248
249 void RelocInfo::Visit(ObjectVisitor* visitor) {
250 RelocInfo::Mode mode = rmode();
251 if (mode == RelocInfo::EMBEDDED_OBJECT) {
252 // RelocInfo is needed when pointer must be updated/serialized, such as
253 // UpdatingVisitor in mark-compact.cc or Serializer in serialize.cc.
254 // It is ignored by visitors that do not need it.
255 // Commenting out, to simplify arch-independednt changes.
256 // GC won't work like this, but this commit is for asm/disasm/sim.
257 // visitor->VisitPointer(target_object_address(), this);
258 } else if (RelocInfo::IsCodeTarget(mode)) {
259 visitor->VisitCodeTarget(this);
260 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
261 // RelocInfo is needed when external-references must be serialized by
262 // Serializer Visitor in serialize.cc. It is ignored by visitors that
263 // do not need it.
264 // Commenting out, to simplify arch-independednt changes.
265 // Serializer won't work like this, but this commit is for asm/disasm/sim.
266 // visitor->VisitExternalReference(target_reference_address(), this);
267 #ifdef ENABLE_DEBUGGER_SUPPORT
268 // TODO(isolates): Get a cached isolate below.
269 } else if (((RelocInfo::IsJSReturn(mode) &&
270 IsPatchedReturnSequence()) ||
271 (RelocInfo::IsDebugBreakSlot(mode) &&
272 IsPatchedDebugBreakSlotSequence())) &&
273 Isolate::Current()->debug()->has_break_points()) {
274 visitor->VisitDebugTarget(this);
275 #endif
276 } else if (mode == RelocInfo::RUNTIME_ENTRY) {
277 visitor->VisitRuntimeEntry(this);
278 }
279 }
280
281
282 template<typename StaticVisitor>
283 void RelocInfo::Visit(Heap* heap) {
284 RelocInfo::Mode mode = rmode();
285 if (mode == RelocInfo::EMBEDDED_OBJECT) {
286 StaticVisitor::VisitPointer(heap, target_object_address());
287 } else if (RelocInfo::IsCodeTarget(mode)) {
288 StaticVisitor::VisitCodeTarget(this);
289 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
290 StaticVisitor::VisitExternalReference(target_reference_address());
291 #ifdef ENABLE_DEBUGGER_SUPPORT
292 } else if (heap->isolate()->debug()->has_break_points() &&
293 ((RelocInfo::IsJSReturn(mode) &&
294 IsPatchedReturnSequence()) ||
295 (RelocInfo::IsDebugBreakSlot(mode) &&
296 IsPatchedDebugBreakSlotSequence()))) {
297 StaticVisitor::VisitDebugTarget(this);
298 #endif
299 } else if (mode == RelocInfo::RUNTIME_ENTRY) {
300 StaticVisitor::VisitRuntimeEntry(this);
301 }
302 }
303
304
195 // ----------------------------------------------------------------------------- 305 // -----------------------------------------------------------------------------
196 // Assembler 306 // Assembler
197 307
198 308
199 void Assembler::CheckBuffer() { 309 void Assembler::CheckBuffer() {
200 if (buffer_space() <= kGap) { 310 if (buffer_space() <= kGap) {
201 GrowBuffer(); 311 GrowBuffer();
202 } 312 }
203 } 313 }
204 314
205 315
316 void Assembler::CheckTrampolinePoolQuick() {
317 if (pc_offset() >= next_buffer_check_) {
318 CheckTrampolinePool();
319 }
320 }
321
322
206 void Assembler::emit(Instr x) { 323 void Assembler::emit(Instr x) {
207 CheckBuffer(); 324 CheckBuffer();
208 *reinterpret_cast<Instr*>(pc_) = x; 325 *reinterpret_cast<Instr*>(pc_) = x;
209 pc_ += kInstrSize; 326 pc_ += kInstrSize;
327 CheckTrampolinePoolQuick();
210 } 328 }
211 329
212 330
213 } } // namespace v8::internal 331 } } // namespace v8::internal
214 332
215 #endif // V8_MIPS_ASSEMBLER_MIPS_INL_H_ 333 #endif // V8_MIPS_ASSEMBLER_MIPS_INL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698