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 40c0f755 Ryan
// 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_