Chromium Code Reviews| 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 |