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

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

Powered by Google App Engine
This is Rietveld 408576698