OLD | NEW |
---|---|
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
232 ScaleFactor scale, | 232 ScaleFactor scale, |
233 int32_t disp) : rex_(0) { | 233 int32_t disp) : rex_(0) { |
234 ASSERT(!index.is(rsp)); | 234 ASSERT(!index.is(rsp)); |
235 len_ = 1; | 235 len_ = 1; |
236 set_modrm(0, rsp); | 236 set_modrm(0, rsp); |
237 set_sib(scale, index, rbp); | 237 set_sib(scale, index, rbp); |
238 set_disp32(disp); | 238 set_disp32(disp); |
239 } | 239 } |
240 | 240 |
241 | 241 |
242 Operand::Operand(const Operand& operand, int32_t offset) { | |
243 ASSERT(operand.len_ >= 1); | |
244 // Operand encodes REX ModR/M [SIB] [Disp]. | |
245 byte modrm = operand.buf_[0]; | |
246 ASSERT(modrm < 0xC0); // Disallow mode 3 (register target). | |
247 bool has_sib = ((modrm & 0x07) == 0x04); | |
248 byte mode = modrm & 0xC0; | |
249 int disp_offset = has_sib ? 2 : 1; | |
250 int base_reg = (has_sib ? operand.buf_[1] : modrm) & 0x07; | |
251 // Mode 0 with rbp/r13 as ModR/M or SIB base register always has a 32-bit | |
252 // displacement. | |
253 bool is_baseless = (mode == 0) && (base_reg == 0x05); // No base or RIP base. | |
254 int32_t disp_value = 0; | |
255 if (mode == 0x80 || is_baseless) { | |
256 // Mode 2 or mode 0 with rbp/r13 as base: Word displacement. | |
257 disp_value = *reinterpret_cast<const int32_t*>(&operand.buf_[disp_offset]); | |
258 } else if (mode == 0x40) { | |
259 // Mode 1: Byte displacement. | |
260 disp_value = static_cast<signed char>(operand.buf_[disp_offset]); | |
261 } | |
262 // Write new operand with same registers, but with modified displacement. | |
William Hesse
2010/05/26 08:13:24
Insert blank line after reading and before writing
Lasse Reichstein
2010/05/26 08:34:11
Done.
| |
263 disp_value += offset; | |
William Hesse
2010/05/26 08:13:24
The assert for no overflow could be added:
ASSERT(
Lasse Reichstein
2010/05/26 08:34:11
Assertion added.
| |
264 rex_ = operand.rex_; | |
265 if (!is_int8(disp_value) || is_baseless) { | |
266 // Need 32 bits of displacement, mode 2 or mode 1 with register rbp/r13. | |
267 buf_[0] = (modrm & 0x3f) | (is_baseless ? 0x00 : 0x80); | |
268 len_ = disp_offset + 4; | |
269 Memory::int32_at(&buf_[disp_offset]) = disp_value; | |
270 } else if (disp_value != 0 || (base_reg == 0x05)) { | |
271 // Need 8 bits of displacement. | |
272 buf_[0] = (modrm & 0x3f) | 0x40; // Mode 1. | |
273 len_ = disp_offset + 1; | |
274 buf_[disp_offset] = static_cast<byte>(disp_value); | |
275 } else { | |
276 // Need no displacement. | |
277 buf_[0] = (modrm & 0x3f); // Mode 0. | |
278 len_ = disp_offset; | |
279 } | |
280 if (has_sib) { | |
281 buf_[1] = operand.buf_[1]; | |
282 } | |
283 } | |
284 | |
242 // ----------------------------------------------------------------------------- | 285 // ----------------------------------------------------------------------------- |
243 // Implementation of Assembler. | 286 // Implementation of Assembler. |
244 | 287 |
245 #ifdef GENERATED_CODE_COVERAGE | 288 #ifdef GENERATED_CODE_COVERAGE |
246 static void InitCoverageLog(); | 289 static void InitCoverageLog(); |
247 #endif | 290 #endif |
248 | 291 |
249 byte* Assembler::spare_buffer_ = NULL; | 292 byte* Assembler::spare_buffer_ = NULL; |
250 | 293 |
251 Assembler::Assembler(void* buffer, int buffer_size) | 294 Assembler::Assembler(void* buffer, int buffer_size) |
(...skipping 2554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2806 // specially coded on x64 means that it is a relative 32 bit address, as used | 2849 // specially coded on x64 means that it is a relative 32 bit address, as used |
2807 // by branch instructions. | 2850 // by branch instructions. |
2808 return (1 << rmode_) & kApplyMask; | 2851 return (1 << rmode_) & kApplyMask; |
2809 } | 2852 } |
2810 | 2853 |
2811 | 2854 |
2812 | 2855 |
2813 } } // namespace v8::internal | 2856 } } // namespace v8::internal |
2814 | 2857 |
2815 #endif // V8_TARGET_ARCH_X64 | 2858 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |