The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / assembler-ia32-inl.h @ 40c0f755

History | View | Annotate | Download (7.88 KB)

1
// Copyright (c) 1994-2006 Sun Microsystems Inc.
2
// All Rights Reserved.
3
//
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are
6
// met:
7
//
8
// - Redistributions of source code must retain the above copyright notice,
9
// this list of conditions and the following disclaimer.
10
//
11
// - Redistribution in binary form must reproduce the above copyright
12
// notice, this list of conditions and the following disclaimer in the
13
// documentation and/or other materials provided with the distribution.
14
//
15
// - Neither the name of Sun Microsystems or the names of contributors may
16
// be used to endorse or promote products derived from this software without
17
// specific prior written permission.
18
//
19
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30

    
31
// The original source code covered by the above license above has been
32
// modified significantly by Google Inc.
33
// Copyright 2006-2008 the V8 project authors. All rights reserved.
34

    
35
// A light-weight IA32 Assembler.
36

    
37
#ifndef V8_ASSEMBLER_IA32_INL_H_
38
#define V8_ASSEMBLER_IA32_INL_H_
39

    
40
#include "cpu.h"
41

    
42
namespace v8 { namespace internal {
43

    
44
Condition NegateCondition(Condition cc) {
45
  return static_cast<Condition>(cc ^ 1);
46
}
47

    
48

    
49
// The modes possibly affected by apply must be in kApplyMask.
50
void RelocInfo::apply(int delta) {
51
  if (rmode_ == RUNTIME_ENTRY || IsCodeTarget(rmode_)) {
52
    int32_t* p = reinterpret_cast<int32_t*>(pc_);
53
    *p -= delta;  // relocate entry
54
  } else if (rmode_ == JS_RETURN && IsCallInstruction()) {
55
    // Special handling of js_return when a break point is set (call
56
    // instruction has been inserted).
57
    int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
58
    *p -= delta;  // relocate entry
59
  } else if (IsInternalReference(rmode_)) {
60
    // absolute code pointer inside code object moves with the code object.
61
    int32_t* p = reinterpret_cast<int32_t*>(pc_);
62
    *p += delta;  // relocate entry
63
  }
64
}
65

    
66

    
67
Address RelocInfo::target_address() {
68
  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
69
  return Assembler::target_address_at(pc_);
70
}
71

    
72

    
73
Address RelocInfo::target_address_address() {
74
  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
75
  return reinterpret_cast<Address>(pc_);
76
}
77

    
78

    
79
void RelocInfo::set_target_address(Address target) {
80
  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
81
  Assembler::set_target_address_at(pc_, target);
82
}
83

    
84

    
85
Object* RelocInfo::target_object() {
86
  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
87
  return *reinterpret_cast<Object**>(pc_);
88
}
89

    
90

    
91
Object** RelocInfo::target_object_address() {
92
  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
93
  return reinterpret_cast<Object**>(pc_);
94
}
95

    
96

    
97
void RelocInfo::set_target_object(Object* target) {
98
  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
99
  *reinterpret_cast<Object**>(pc_) = target;
100
}
101

    
102

    
103
Address* RelocInfo::target_reference_address() {
104
  ASSERT(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
105
  return reinterpret_cast<Address*>(pc_);
106
}
107

    
108

    
109
Address RelocInfo::call_address() {
110
  ASSERT(IsCallInstruction());
111
  return Assembler::target_address_at(pc_ + 1);
112
}
113

    
114

    
115
void RelocInfo::set_call_address(Address target) {
116
  ASSERT(IsCallInstruction());
117
  Assembler::set_target_address_at(pc_ + 1, target);
118
}
119

    
120

    
121
Object* RelocInfo::call_object() {
122
  ASSERT(IsCallInstruction());
123
  return *call_object_address();
124
}
125

    
126

    
127
Object** RelocInfo::call_object_address() {
128
  ASSERT(IsCallInstruction());
129
  return reinterpret_cast<Object**>(pc_ + 1);
130
}
131

    
132

    
133
void RelocInfo::set_call_object(Object* target) {
134
  ASSERT(IsCallInstruction());
135
  *call_object_address() = target;
136
}
137

    
138

    
139
bool RelocInfo::IsCallInstruction() {
140
  return *pc_ == 0xE8;
141
}
142

    
143

    
144
Immediate::Immediate(int x)  {
145
  x_ = x;
146
  rmode_ = RelocInfo::NONE;
147
}
148

    
149

    
150
Immediate::Immediate(const ExternalReference& ext) {
151
  x_ = reinterpret_cast<int32_t>(ext.address());
152
  rmode_ = RelocInfo::EXTERNAL_REFERENCE;
153
}
154

    
155
Immediate::Immediate(const char* s) {
156
  x_ = reinterpret_cast<int32_t>(s);
157
  rmode_ = RelocInfo::EMBEDDED_STRING;
158
}
159

    
160

    
161
Immediate::Immediate(Label *internal_offset) {
162
  x_ = reinterpret_cast<int32_t>(internal_offset);
163
  rmode_ = RelocInfo::INTERNAL_REFERENCE;
164
}
165

    
166

    
167
Immediate::Immediate(Handle<Object> handle) {
168
  // Verify all Objects referred by code are NOT in new space.
169
  Object* obj = *handle;
170
  ASSERT(!Heap::InNewSpace(obj));
171
  if (obj->IsHeapObject()) {
172
    x_ = reinterpret_cast<intptr_t>(handle.location());
173
    rmode_ = RelocInfo::EMBEDDED_OBJECT;
174
  } else {
175
    // no relocation needed
176
    x_ =  reinterpret_cast<intptr_t>(obj);
177
    rmode_ = RelocInfo::NONE;
178
  }
179
}
180

    
181

    
182
Immediate::Immediate(Smi* value) {
183
  x_ = reinterpret_cast<intptr_t>(value);
184
  rmode_ = RelocInfo::NONE;
185
}
186

    
187

    
188
void Assembler::emit(uint32_t x) {
189
  *reinterpret_cast<uint32_t*>(pc_) = x;
190
  pc_ += sizeof(uint32_t);
191
}
192

    
193

    
194
void Assembler::emit(Handle<Object> handle) {
195
  // Verify all Objects referred by code are NOT in new space.
196
  Object* obj = *handle;
197
  ASSERT(!Heap::InNewSpace(obj));
198
  if (obj->IsHeapObject()) {
199
    emit(reinterpret_cast<intptr_t>(handle.location()),
200
         RelocInfo::EMBEDDED_OBJECT);
201
  } else {
202
    // no relocation needed
203
    emit(reinterpret_cast<intptr_t>(obj));
204
  }
205
}
206

    
207

    
208
void Assembler::emit(uint32_t x, RelocInfo::Mode rmode) {
209
  if (rmode != RelocInfo::NONE) RecordRelocInfo(rmode);
210
  emit(x);
211
}
212

    
213

    
214
void Assembler::emit(const Immediate& x) {
215
  if (x.rmode_ == RelocInfo::INTERNAL_REFERENCE) {
216
    Label* label = reinterpret_cast<Label*>(x.x_);
217
    emit_code_relative_offset(label);
218
    return;
219
  }
220
  if (x.rmode_ != RelocInfo::NONE) RecordRelocInfo(x.rmode_);
221
  emit(x.x_);
222
}
223

    
224

    
225
void Assembler::emit_code_relative_offset(Label* label) {
226
  if (label->is_bound()) {
227
    int32_t pos;
228
    pos = label->pos() + Code::kHeaderSize - kHeapObjectTag;
229
    emit(pos);
230
  } else {
231
    emit_disp(label, Displacement::CODE_RELATIVE);
232
  }
233
}
234

    
235

    
236
void Assembler::emit_w(const Immediate& x) {
237
  ASSERT(x.rmode_ == RelocInfo::NONE);
238
  uint16_t value = static_cast<uint16_t>(x.x_);
239
  reinterpret_cast<uint16_t*>(pc_)[0] = value;
240
  pc_ += sizeof(uint16_t);
241
}
242

    
243

    
244
Address Assembler::target_address_at(Address pc) {
245
  return pc + sizeof(int32_t) + *reinterpret_cast<int32_t*>(pc);
246
}
247

    
248

    
249
void Assembler::set_target_address_at(Address pc, Address target) {
250
  int32_t* p = reinterpret_cast<int32_t*>(pc);
251
  *p = target - (pc + sizeof(int32_t));
252
  CPU::FlushICache(p, sizeof(int32_t));
253
}
254

    
255

    
256
Displacement Assembler::disp_at(Label* L) {
257
  return Displacement(long_at(L->pos()));
258
}
259

    
260

    
261
void Assembler::disp_at_put(Label* L, Displacement disp) {
262
  long_at_put(L->pos(), disp.data());
263
}
264

    
265

    
266
void Assembler::emit_disp(Label* L, Displacement::Type type) {
267
  Displacement disp(L, type);
268
  L->link_to(pc_offset());
269
  emit(static_cast<int>(disp.data()));
270
}
271

    
272

    
273
void Operand::set_modrm(int mod, Register rm) {
274
  ASSERT((mod & -4) == 0);
275
  buf_[0] = mod << 6 | rm.code();
276
  len_ = 1;
277
}
278

    
279

    
280
void Operand::set_dispr(int32_t disp, RelocInfo::Mode rmode) {
281
  ASSERT(len_ == 1 || len_ == 2);
282
  int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]);
283
  *p = disp;
284
  len_ += sizeof(int32_t);
285
  rmode_ = rmode;
286
}
287

    
288
Operand::Operand(Register reg) {
289
  // reg
290
  set_modrm(3, reg);
291
}
292

    
293

    
294
Operand::Operand(int32_t disp, RelocInfo::Mode rmode) {
295
  // [disp/r]
296
  set_modrm(0, ebp);
297
  set_dispr(disp, rmode);
298
}
299

    
300
} }  // namespace v8::internal
301

    
302
#endif  // V8_ASSEMBLER_IA32_INL_H_