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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 | 63 |
64 | 64 |
65 // The high bit of reg is used for REX.R, the high bit of op's base | 65 // The high bit of reg is used for REX.R, the high bit of op's base |
66 // register is used for REX.B, and the high bit of op's index register | 66 // register is used for REX.B, and the high bit of op's index register |
67 // is used for REX.X. REX.W is set. | 67 // is used for REX.X. REX.W is set. |
68 void Assembler::emit_rex_64(Register reg, const Operand& op) { | 68 void Assembler::emit_rex_64(Register reg, const Operand& op) { |
69 emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex_); | 69 emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex_); |
70 } | 70 } |
71 | 71 |
72 | 72 |
73 // The high bit of the register is used for REX.B. | |
74 // REX.W is set and REX.R and REX.X are clear. | |
75 void Assembler::emit_rex_64(Register rm_reg) { | |
76 ASSERT_EQ(rm_reg.code() & 0x0f, rm_reg.code()); | |
77 emit(0x48 | (rm_reg.code() >> 3)); | |
William Hesse
2009/05/29 13:08:00
There was never a good reason for putting these in
| |
78 } | |
79 | |
80 | |
81 // The high bit of op's base register is used for REX.B, and the high | |
82 // bit of op's index register is used for REX.X. REX.W is set and REX.R clear. | |
83 void Assembler::emit_rex_64(const Operand& op) { | |
84 emit(0x48 | op.rex_); | |
85 } | |
86 | |
87 | |
73 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. | 88 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. |
74 // REX.W is set. REX.X is cleared. | 89 // REX.W and REX.X are clear. |
75 void Assembler::emit_rex_32(Register reg, Register rm_reg) { | 90 void Assembler::emit_rex_32(Register reg, Register rm_reg) { |
76 emit(0x40 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3); | 91 emit(0x40 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3); |
77 } | 92 } |
78 | 93 |
79 | 94 |
80 // The high bit of reg is used for REX.R, the high bit of op's base | 95 // The high bit of reg is used for REX.R, the high bit of op's base |
81 // register is used for REX.B, and the high bit of op's index register | 96 // register is used for REX.B, and the high bit of op's index register |
82 // is used for REX.X. REX.W is cleared. | 97 // is used for REX.X. REX.W is cleared. |
83 void Assembler::emit_rex_32(Register reg, const Operand& op) { | 98 void Assembler::emit_rex_32(Register reg, const Operand& op) { |
84 emit(0x40 | (reg.code() & 0x8) >> 1 | op.rex_); | 99 emit(0x40 | (reg.code() & 0x8) >> 1 | op.rex_); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
215 return reinterpret_cast<Object**>(pc_ + 1); | 230 return reinterpret_cast<Object**>(pc_ + 1); |
216 } | 231 } |
217 | 232 |
218 // ----------------------------------------------------------------------------- | 233 // ----------------------------------------------------------------------------- |
219 // Implementation of Operand | 234 // Implementation of Operand |
220 | 235 |
221 Operand::Operand(Register base, int32_t disp) { | 236 Operand::Operand(Register base, int32_t disp) { |
222 len_ = 1; | 237 len_ = 1; |
223 if (base.is(rsp) || base.is(r12)) { | 238 if (base.is(rsp) || base.is(r12)) { |
224 // SIB byte is needed to encode (rsp + offset) or (r12 + offset). | 239 // SIB byte is needed to encode (rsp + offset) or (r12 + offset). |
225 set_sib(times_1, rsp, base); | 240 set_sib(kTimes1, rsp, base); |
226 } | 241 } |
227 | 242 |
228 if (disp == 0 && !base.is(rbp) && !base.is(r13)) { | 243 if (disp == 0 && !base.is(rbp) && !base.is(r13)) { |
229 set_modrm(0, rsp); | 244 set_modrm(0, rsp); |
230 } else if (is_int8(disp)) { | 245 } else if (is_int8(disp)) { |
231 set_modrm(1, base); | 246 set_modrm(1, base); |
232 set_disp8(disp); | 247 set_disp8(disp); |
233 } else { | 248 } else { |
234 set_modrm(2, base); | 249 set_modrm(2, base); |
235 set_disp32(disp); | 250 set_disp32(disp); |
236 } | 251 } |
237 } | 252 } |
238 | 253 |
239 void Operand::set_modrm(int mod, Register rm) { | 254 void Operand::set_modrm(int mod, Register rm) { |
240 ASSERT((mod & -4) == 0); | 255 ASSERT((mod & -4) == 0); |
241 buf_[0] = mod << 6 | (rm.code() & 0x7); | 256 buf_[0] = mod << 6 | (rm.code() & 0x7); |
242 // Set REX.B to the high bit of rm.code(). | 257 // Set REX.B to the high bit of rm.code(). |
243 rex_ |= (rm.code() >> 3); | 258 rex_ |= (rm.code() >> 3); |
244 } | 259 } |
245 | 260 |
246 | 261 |
247 void Operand::set_sib(ScaleFactor scale, Register index, Register base) { | 262 void Operand::set_sib(ScaleFactor scale, Register index, Register base) { |
248 ASSERT(len_ == 1); | 263 ASSERT(len_ == 1); |
249 ASSERT((scale & -4) == 0); | 264 ASSERT(is_uint2(scale)); |
250 // Use SIB with no index register only for base rsp or r12. | 265 // Use SIB with no index register only for base rsp or r12. |
251 ASSERT(!index.is(rsp) || base.is(rsp) || base.is(r12)); | 266 ASSERT(!index.is(rsp) || base.is(rsp) || base.is(r12)); |
252 buf_[1] = scale << 6 | (index.code() & 0x7) << 3 | (base.code() & 0x7); | 267 buf_[1] = scale << 6 | (index.code() & 0x7) << 3 | (base.code() & 0x7); |
253 rex_ |= (index.code() >> 3) << 1 | base.code() >> 3; | 268 rex_ |= (index.code() >> 3) << 1 | base.code() >> 3; |
254 len_ = 2; | 269 len_ = 2; |
255 } | 270 } |
256 | 271 |
257 void Operand::set_disp8(int disp) { | 272 void Operand::set_disp8(int disp) { |
258 ASSERT(is_int8(disp)); | 273 ASSERT(is_int8(disp)); |
259 ASSERT(len_ == 1 || len_ == 2); | 274 ASSERT(len_ == 1 || len_ == 2); |
260 int8_t* p = reinterpret_cast<int8_t*>(&buf_[len_]); | 275 int8_t* p = reinterpret_cast<int8_t*>(&buf_[len_]); |
261 *p = disp; | 276 *p = disp; |
262 len_ += sizeof(int8_t); | 277 len_ += sizeof(int8_t); |
263 } | 278 } |
264 | 279 |
265 void Operand::set_disp32(int disp) { | 280 void Operand::set_disp32(int disp) { |
266 ASSERT(len_ == 1 || len_ == 2); | 281 ASSERT(len_ == 1 || len_ == 2); |
267 int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); | 282 int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); |
268 *p = disp; | 283 *p = disp; |
269 len_ += sizeof(int32_t); | 284 len_ += sizeof(int32_t); |
270 } | 285 } |
271 | 286 |
272 | 287 |
273 } } // namespace v8::internal | 288 } } // namespace v8::internal |
274 | 289 |
275 #endif // V8_X64_ASSEMBLER_X64_INL_H_ | 290 #endif // V8_X64_ASSEMBLER_X64_INL_H_ |
OLD | NEW |