Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: runtime/vm/assembler_x64.cc

Issue 8818001: Add 64-bit stubs to call into the runtime and to call native functions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/assembler_x64_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/heap.h" 9 #include "vm/heap.h"
10 #include "vm/memory_region.h" 10 #include "vm/memory_region.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 56
57 57
58 void Assembler::pushq(const Address& address) { 58 void Assembler::pushq(const Address& address) {
59 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 59 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
60 EmitOperandREX(6, address, REX_NONE); 60 EmitOperandREX(6, address, REX_NONE);
61 EmitUint8(0xFF); 61 EmitUint8(0xFF);
62 EmitOperand(6, address); 62 EmitOperand(6, address);
63 } 63 }
64 64
65 65
66 void Assembler::pushq(const Immediate& imm) {
67 if (imm.is_int32()) {
68 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
69 EmitUint8(0x68);
70 EmitImmediate(imm);
71 } else {
72 movq(TMP, imm);
73 pushq(TMP);
74 }
75 }
76
77
66 void Assembler::popq(Register reg) { 78 void Assembler::popq(Register reg) {
67 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 79 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
68 EmitRegisterREX(reg, REX_NONE); 80 EmitRegisterREX(reg, REX_NONE);
69 EmitUint8(0x58 | (reg & 7)); 81 EmitUint8(0x58 | (reg & 7));
70 } 82 }
71 83
72 84
73 void Assembler::popq(const Address& address) { 85 void Assembler::popq(const Address& address) {
74 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 86 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
75 EmitOperandREX(0, address, REX_NONE); 87 EmitOperandREX(0, address, REX_NONE);
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 280
269 void Assembler::movq(const Address& dst, Register src) { 281 void Assembler::movq(const Address& dst, Register src) {
270 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 282 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
271 EmitOperandREX(src, dst, REX_W); 283 EmitOperandREX(src, dst, REX_W);
272 EmitUint8(0x89); 284 EmitUint8(0x89);
273 EmitOperand(src & 7, dst); 285 EmitOperand(src & 7, dst);
274 } 286 }
275 287
276 288
277 void Assembler::movq(const Address& dst, const Immediate& imm) { 289 void Assembler::movq(const Address& dst, const Immediate& imm) {
278 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 290 if (imm.is_int32()) {
279 ASSERT(imm.is_int32()); 291 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
280 Operand operand(dst); 292 Operand operand(dst);
281 EmitOperandREX(0, operand, REX_W); 293 EmitOperandREX(0, operand, REX_W);
282 EmitUint8(0xC7); 294 EmitUint8(0xC7);
283 EmitOperand(0, operand); 295 EmitOperand(0, operand);
284 EmitImmediate(imm); 296 EmitImmediate(imm);
297 } else {
298 movq(TMP, imm);
299 movq(dst, TMP);
300 }
285 } 301 }
286 302
287 303
288 void Assembler::movsxl(Register dst, const Address& src) { 304 void Assembler::movsxl(Register dst, const Address& src) {
289 UNIMPLEMENTED(); 305 UNIMPLEMENTED();
290 } 306 }
291 307
292 308
293 void Assembler::leaq(Register dst, const Address& src) { 309 void Assembler::leaq(Register dst, const Address& src) {
294 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 310 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 EmitXmmRegisterOperand(src & 7, dst); 349 EmitXmmRegisterOperand(src & 7, dst);
334 } 350 }
335 351
336 352
337 void Assembler::movd(XmmRegister dst, Register src) { 353 void Assembler::movd(XmmRegister dst, Register src) {
338 ASSERT(dst <= XMM7); 354 ASSERT(dst <= XMM7);
339 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 355 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
340 EmitUint8(0x66); 356 EmitUint8(0x66);
341 EmitUint8(0x0F); 357 EmitUint8(0x0F);
342 EmitUint8(0x6E); 358 EmitUint8(0x6E);
343 EmitOperand(dst, Operand(src)); 359 EmitOperand(dst & 7, Operand(src));
344 } 360 }
345 361
346 362
347 void Assembler::movd(Register dst, XmmRegister src) { 363 void Assembler::movd(Register dst, XmmRegister src) {
348 ASSERT(src <= XMM7); 364 ASSERT(src <= XMM7);
349 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 365 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
350 EmitUint8(0x66); 366 EmitUint8(0x66);
351 EmitUint8(0x0F); 367 EmitUint8(0x0F);
352 EmitUint8(0x7E); 368 EmitUint8(0x7E);
353 EmitOperand(src, Operand(dst)); 369 EmitOperand(src & 7, Operand(dst));
354 } 370 }
355 371
356 372
357 void Assembler::addss(XmmRegister dst, XmmRegister src) { 373 void Assembler::addss(XmmRegister dst, XmmRegister src) {
358 // TODO(srdjan): implement and test XMM8 - XMM15. 374 // TODO(srdjan): implement and test XMM8 - XMM15.
359 ASSERT(src <= XMM7); 375 ASSERT(src <= XMM7);
360 ASSERT(dst <= XMM7); 376 ASSERT(dst <= XMM7);
361 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 377 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
362 EmitUint8(0xF3); 378 EmitUint8(0xF3);
363 EmitUint8(0x0F); 379 EmitUint8(0x0F);
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 545
530 546
531 void Assembler::cmpl(const Address& address, const Immediate& imm) { 547 void Assembler::cmpl(const Address& address, const Immediate& imm) {
532 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 548 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
533 Operand operand(address); 549 Operand operand(address);
534 EmitOperandREX(7, operand, REX_NONE); 550 EmitOperandREX(7, operand, REX_NONE);
535 EmitComplex(7, operand, imm); 551 EmitComplex(7, operand, imm);
536 } 552 }
537 553
538 554
555 void Assembler::cmpq(const Address& address, Register reg) {
556 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
557 EmitOperandREX(reg, address, REX_W);
558 EmitUint8(0x39);
559 EmitOperand(reg & 7, address);
560 }
561
562
539 void Assembler::cmpq(const Address& address, const Immediate& imm) { 563 void Assembler::cmpq(const Address& address, const Immediate& imm) {
540 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 564 if (imm.is_int32()) {
541 Operand operand(address); 565 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
542 EmitOperandREX(7, operand, REX_W); 566 Operand operand(address);
543 EmitComplex(7, operand, imm); 567 EmitOperandREX(7, operand, REX_W);
568 EmitComplex(7, operand, imm);
569 } else {
570 movq(TMP, imm);
571 cmpq(address, TMP);
572 }
544 } 573 }
545 574
546 575
547 void Assembler::cmpq(Register reg, const Immediate& imm) { 576 void Assembler::cmpq(Register reg, const Immediate& imm) {
548 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 577 if (imm.is_int32()) {
549 EmitRegisterREX(reg, REX_W); 578 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
550 EmitComplex(7, Operand(reg), imm); 579 EmitRegisterREX(reg, REX_W);
580 EmitComplex(7, Operand(reg), imm);
581 } else {
582 movq(TMP, imm);
583 cmpq(reg, TMP);
584 }
551 } 585 }
552 586
553 587
554 void Assembler::cmpq(Register reg0, Register reg1) { 588 void Assembler::cmpq(Register reg0, Register reg1) {
555 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 589 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
556 Operand operand(reg1); 590 Operand operand(reg1);
557 EmitOperandREX(reg0, operand, REX_W); 591 EmitOperandREX(reg0, operand, REX_W);
558 EmitUint8(0x3B); 592 EmitUint8(0x3B);
559 EmitOperand(reg0 & 7, operand); 593 EmitOperand(reg0 & 7, operand);
560 } 594 }
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 void Assembler::idivq(Register reg) { 832 void Assembler::idivq(Register reg) {
799 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 833 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
800 EmitRegisterREX(reg, REX_W); 834 EmitRegisterREX(reg, REX_W);
801 EmitUint8(0xF7); 835 EmitUint8(0xF7);
802 EmitUint8(0xF8 | (reg & 7)); 836 EmitUint8(0xF8 | (reg & 7));
803 } 837 }
804 838
805 839
806 void Assembler::imull(Register dst, Register src) { 840 void Assembler::imull(Register dst, Register src) {
807 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 841 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
842 Operand operand(src);
843 EmitOperandREX(dst, operand, REX_NONE);
808 EmitUint8(0x0F); 844 EmitUint8(0x0F);
809 EmitUint8(0xAF); 845 EmitUint8(0xAF);
810 EmitOperand(dst, Operand(src)); 846 EmitOperand(dst & 7, Operand(src));
811 } 847 }
812 848
813 849
814 void Assembler::imull(Register reg, const Immediate& imm) { 850 void Assembler::imull(Register reg, const Immediate& imm) {
815 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 851 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
852 EmitRegisterREX(reg, REX_NONE);
816 EmitUint8(0x69); 853 EmitUint8(0x69);
817 EmitOperand(reg, Operand(reg)); 854 EmitOperand(reg & 7, Operand(reg));
818 EmitImmediate(imm); 855 EmitImmediate(imm);
819 } 856 }
820 857
821 858
822 void Assembler::imulq(Register dst, Register src) { 859 void Assembler::imulq(Register dst, Register src) {
823 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 860 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
824 Operand operand(src); 861 Operand operand(src);
825 EmitOperandREX(dst, operand, REX_W); 862 EmitOperandREX(dst, operand, REX_W);
826 EmitUint8(0x0F); 863 EmitUint8(0x0F);
827 EmitUint8(0xAF); 864 EmitUint8(0xAF);
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 if (value == 1) { 1154 if (value == 1) {
1118 decq(reg); 1155 decq(reg);
1119 } else if (value != 0) { 1156 } else if (value != 0) {
1120 subq(reg, Immediate(value)); 1157 subq(reg, Immediate(value));
1121 } 1158 }
1122 } 1159 }
1123 } 1160 }
1124 1161
1125 1162
1126 void Assembler::LoadObject(Register dst, const Object& object) { 1163 void Assembler::LoadObject(Register dst, const Object& object) {
1127 ASSERT(object.IsZoneHandle()); 1164 if (object.IsSmi()) {
1128 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1165 movq(dst, Immediate(reinterpret_cast<int64_t>(object.raw())));
1129 EmitRegisterREX(dst, REX_W); 1166 } else {
1130 EmitUint8(0xB8 | (dst & 7)); 1167 ASSERT(object.IsZoneHandle());
1131 buffer_.EmitObject(object); 1168 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1169 EmitRegisterREX(dst, REX_W);
1170 EmitUint8(0xB8 | (dst & 7));
1171 buffer_.EmitObject(object);
1172 }
1132 } 1173 }
1133 1174
1134 1175
1135 void Assembler::PushObject(const Object& object) { 1176 void Assembler::PushObject(const Object& object) {
1136 LoadObject(TMP, object); 1177 if (object.IsSmi()) {
1137 pushq(TMP); 1178 pushq(Immediate(reinterpret_cast<int64_t>(object.raw())));
1179 } else {
1180 LoadObject(TMP, object);
1181 pushq(TMP);
1182 }
1138 } 1183 }
1139 1184
1140 1185
1141 void Assembler::CompareObject(Register reg, const Object& object) { 1186 void Assembler::CompareObject(Register reg, const Object& object) {
1142 ASSERT(reg != TMP); 1187 if (object.IsSmi()) {
1143 LoadObject(TMP, object); 1188 cmpq(reg, Immediate(reinterpret_cast<int64_t>(object.raw())));
1144 cmpq(reg, TMP); 1189 } else {
1190 ASSERT(reg != TMP);
1191 LoadObject(TMP, object);
1192 cmpq(reg, TMP);
1193 }
1145 } 1194 }
1146 1195
1147 1196
1148 void Assembler::Stop(const char* message) { 1197 void Assembler::Stop(const char* message) {
1149 // Emit the lower half and the higher half of the message address as immediate 1198 // Emit the lower half and the higher half of the message address as immediate
1150 // operands in the test rax instructions, followed by the int3 instruction. 1199 // operands in the test rax instructions, followed by the int3 instruction.
1151 // Execution can be resumed with the 'cont' command in gdb. 1200 // Execution can be resumed with the 'cont' command in gdb.
1152 int64_t message_address = reinterpret_cast<int64_t>(message); 1201 int64_t message_address = reinterpret_cast<int64_t>(message);
1153 testl(RAX, Immediate(Utils::Low32Bits(message_address))); 1202 testl(RAX, Immediate(Utils::Low32Bits(message_address)));
1154 testl(RAX, Immediate(Utils::High32Bits(message_address))); 1203 testl(RAX, Immediate(Utils::High32Bits(message_address)));
(...skipping 13 matching lines...) Expand all
1168 while (label->HasNear()) { 1217 while (label->HasNear()) {
1169 int position = label->NearPosition(); 1218 int position = label->NearPosition();
1170 int offset = bound - (position + 1); 1219 int offset = bound - (position + 1);
1171 ASSERT(Utils::IsInt(8, offset)); 1220 ASSERT(Utils::IsInt(8, offset));
1172 buffer_.Store<int8_t>(position, offset); 1221 buffer_.Store<int8_t>(position, offset);
1173 } 1222 }
1174 label->BindTo(bound); 1223 label->BindTo(bound);
1175 } 1224 }
1176 1225
1177 1226
1227 void Assembler::EnterFrame(intptr_t frame_size) {
1228 if (prolog_offset_ == -1) {
1229 prolog_offset_ = CodeSize();
1230 }
1231 pushq(RBP);
1232 movq(RBP, RSP);
1233 if (frame_size != 0) {
1234 Immediate frame_space(frame_size);
1235 subq(RSP, frame_space);
1236 }
1237 }
1238
1239
1240 void Assembler::LeaveFrame() {
1241 movq(RSP, RBP);
1242 popq(RBP);
1243 }
1244
1245
1246 void Assembler::CallRuntimeFromDart(const RuntimeEntry& entry) {
1247 entry.CallFromDart(this);
1248 }
1249
1250
1251 void Assembler::CallRuntimeFromStub(const RuntimeEntry& entry) {
1252 entry.CallFromStub(this);
1253 }
1254
1255
1178 void Assembler::Align(int alignment, int offset) { 1256 void Assembler::Align(int alignment, int offset) {
1179 UNIMPLEMENTED(); 1257 UNIMPLEMENTED();
1180 } 1258 }
1181 1259
1182 1260
1183 void Assembler::EmitOperand(int rm, const Operand& operand) { 1261 void Assembler::EmitOperand(int rm, const Operand& operand) {
1184 ASSERT(rm >= 0 && rm < 8); 1262 ASSERT(rm >= 0 && rm < 8);
1185 const int length = operand.length_; 1263 const int length = operand.length_;
1186 ASSERT(length > 0); 1264 ASSERT(length > 0);
1187 // Emit the ModRM byte updated with the given RM value. 1265 // Emit the ModRM byte updated with the given RM value.
(...skipping 16 matching lines...) Expand all
1204 void Assembler::EmitImmediate(const Immediate& imm) { 1282 void Assembler::EmitImmediate(const Immediate& imm) {
1205 if (imm.is_int32()) { 1283 if (imm.is_int32()) {
1206 EmitInt32(static_cast<int32_t>(imm.value())); 1284 EmitInt32(static_cast<int32_t>(imm.value()));
1207 } else { 1285 } else {
1208 EmitInt64(imm.value()); 1286 EmitInt64(imm.value());
1209 } 1287 }
1210 } 1288 }
1211 1289
1212 1290
1213 void Assembler::EmitComplex(int rm, 1291 void Assembler::EmitComplex(int rm,
1214 const Operand& operand, 1292 const Operand& operand,
1215 const Immediate& immediate) { 1293 const Immediate& immediate) {
1216 ASSERT(rm >= 0 && rm < 8); 1294 ASSERT(rm >= 0 && rm < 8);
1217 ASSERT(immediate.is_int32()); 1295 ASSERT(immediate.is_int32());
1218 if (immediate.is_int8()) { 1296 if (immediate.is_int8()) {
1219 // Use sign-extended 8-bit immediate. 1297 // Use sign-extended 8-bit immediate.
1220 EmitUint8(0x83); 1298 EmitUint8(0x83);
1221 EmitOperand(rm, operand); 1299 EmitOperand(rm, operand);
1222 EmitUint8(immediate.value() & 0xFF); 1300 EmitUint8(immediate.value() & 0xFF);
1223 } else if (operand.IsRegister(RAX)) { 1301 } else if (operand.IsRegister(RAX)) {
1224 // Use short form if the destination is rax. 1302 // Use short form if the destination is rax.
1225 EmitUint8(0x05 + (rm << 3)); 1303 EmitUint8(0x05 + (rm << 3));
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 } else { 1370 } else {
1293 EmitRegisterREX(operand, REX_NONE); 1371 EmitRegisterREX(operand, REX_NONE);
1294 } 1372 }
1295 EmitUint8(0xD3); 1373 EmitUint8(0xD3);
1296 EmitOperand(rm, Operand(operand)); 1374 EmitOperand(rm, Operand(operand));
1297 } 1375 }
1298 1376
1299 } // namespace dart 1377 } // namespace dart
1300 1378
1301 #endif // defined TARGET_ARCH_X64 1379 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/assembler_x64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698