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

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

Issue 8984003: Port code generator to x64. (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 25 matching lines...) Expand all
36 36
37 void Assembler::call(Label* label) { 37 void Assembler::call(Label* label) {
38 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 38 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
39 static const int kSize = 5; 39 static const int kSize = 5;
40 EmitUint8(0xE8); 40 EmitUint8(0xE8);
41 EmitLabel(label, kSize); 41 EmitLabel(label, kSize);
42 } 42 }
43 43
44 44
45 void Assembler::call(const ExternalLabel* label) { 45 void Assembler::call(const ExternalLabel* label) {
46 movq(TMP, Immediate(label->address())); 46 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
47 call(TMP); 47 intptr_t call_start = buffer_.GetPosition();
48
49 // Encode movq(TMP, Immediate(label->address())), but always as imm64.
50 EmitRegisterREX(TMP, REX_W);
51 EmitUint8(0xB8 | (TMP & 7));
52 EmitInt64(label->address());
53
54 // Encode call(TMP).
55 Operand operand(TMP);
56 EmitOperandREX(2, operand, REX_NONE);
57 EmitUint8(0xFF);
58 EmitOperand(2, operand);
59
60 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize);
48 } 61 }
49 62
50 63
51 void Assembler::pushq(Register reg) { 64 void Assembler::pushq(Register reg) {
52 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 65 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
53 EmitRegisterREX(reg, REX_NONE); 66 EmitRegisterREX(reg, REX_NONE);
54 EmitUint8(0x50 | (reg & 7)); 67 EmitUint8(0x50 | (reg & 7));
55 } 68 }
56 69
57 70
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 } 888 }
876 889
877 890
878 void Assembler::subq(Register reg, const Immediate& imm) { 891 void Assembler::subq(Register reg, const Immediate& imm) {
879 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 892 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
880 EmitRegisterREX(reg, REX_W); 893 EmitRegisterREX(reg, REX_W);
881 EmitComplex(5, Operand(reg), imm); 894 EmitComplex(5, Operand(reg), imm);
882 } 895 }
883 896
884 897
898 void Assembler::subq(Register reg, const Address& address) {
899 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
900 EmitOperandREX(reg, address, REX_W);
901 EmitUint8(0x2B);
902 EmitOperand(reg & 7, address);
903 }
904
905
885 void Assembler::shll(Register reg, const Immediate& imm) { 906 void Assembler::shll(Register reg, const Immediate& imm) {
886 EmitGenericShift(false, 4, reg, imm); 907 EmitGenericShift(false, 4, reg, imm);
887 } 908 }
888 909
889 910
890 void Assembler::shll(Register operand, Register shifter) { 911 void Assembler::shll(Register operand, Register shifter) {
891 EmitGenericShift(false, 4, operand, shifter); 912 EmitGenericShift(false, 4, operand, shifter);
892 } 913 }
893 914
894 915
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 EmitUint8(0xC9); 1048 EmitUint8(0xC9);
1028 } 1049 }
1029 1050
1030 1051
1031 void Assembler::ret() { 1052 void Assembler::ret() {
1032 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1053 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1033 EmitUint8(0xC3); 1054 EmitUint8(0xC3);
1034 } 1055 }
1035 1056
1036 1057
1037 void Assembler::nop() { 1058 void Assembler::nop(int size) {
1038 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1059 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1039 EmitUint8(0x90); 1060 // There are nops up to size 15, but for now just provide up to size 8.
1061 ASSERT(0 < size && size <= MAX_NOP_SIZE);
1062 switch (size) {
1063 case 1:
1064 EmitUint8(0x90);
1065 break;
1066 case 2:
1067 EmitUint8(0x66);
1068 EmitUint8(0x90);
1069 break;
1070 case 3:
1071 EmitUint8(0x0F);
1072 EmitUint8(0x1F);
1073 EmitUint8(0x00);
1074 break;
1075 case 4:
1076 EmitUint8(0x0F);
1077 EmitUint8(0x1F);
1078 EmitUint8(0x40);
1079 EmitUint8(0x00);
1080 break;
1081 case 5:
1082 EmitUint8(0x0F);
1083 EmitUint8(0x1F);
1084 EmitUint8(0x44);
1085 EmitUint8(0x00);
1086 EmitUint8(0x00);
1087 break;
1088 case 6:
1089 EmitUint8(0x66);
1090 EmitUint8(0x0F);
1091 EmitUint8(0x1F);
1092 EmitUint8(0x44);
1093 EmitUint8(0x00);
1094 EmitUint8(0x00);
1095 break;
1096 case 7:
1097 EmitUint8(0x0F);
1098 EmitUint8(0x1F);
1099 EmitUint8(0x80);
1100 EmitUint8(0x00);
1101 EmitUint8(0x00);
1102 EmitUint8(0x00);
1103 EmitUint8(0x00);
1104 break;
1105 case 8:
1106 EmitUint8(0x0F);
1107 EmitUint8(0x1F);
1108 EmitUint8(0x84);
1109 EmitUint8(0x00);
1110 EmitUint8(0x00);
1111 EmitUint8(0x00);
1112 EmitUint8(0x00);
1113 EmitUint8(0x00);
1114 break;
1115 default:
1116 UNIMPLEMENTED();
1117 }
1040 } 1118 }
1041 1119
1042 1120
1043 void Assembler::int3() { 1121 void Assembler::int3() {
1044 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1122 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1045 EmitUint8(0xCC); 1123 EmitUint8(0xCC);
1046 } 1124 }
1047 1125
1048 1126
1049 void Assembler::hlt() { 1127 void Assembler::hlt() {
(...skipping 21 matching lines...) Expand all
1071 EmitUint8(0x70 + condition); 1149 EmitUint8(0x70 + condition);
1072 EmitNearLabelLink(label); 1150 EmitNearLabelLink(label);
1073 } else { 1151 } else {
1074 EmitUint8(0x0F); 1152 EmitUint8(0x0F);
1075 EmitUint8(0x80 + condition); 1153 EmitUint8(0x80 + condition);
1076 EmitLabelLink(label); 1154 EmitLabelLink(label);
1077 } 1155 }
1078 } 1156 }
1079 1157
1080 1158
1159 void Assembler::j(Condition condition, const ExternalLabel* label) {
1160 Label no_jump;
1161 j(static_cast<Condition>(condition ^ 1), &no_jump); // Negate condition.
1162 jmp(label);
1163 Bind(&no_jump);
1164 }
1165
1166
1081 void Assembler::jmp(Register reg) { 1167 void Assembler::jmp(Register reg) {
1082 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1168 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1083 Operand operand(reg); 1169 Operand operand(reg);
1084 EmitOperandREX(4, operand, REX_NONE); 1170 EmitOperandREX(4, operand, REX_NONE);
1085 EmitUint8(0xFF); 1171 EmitUint8(0xFF);
1086 EmitOperand(4, operand); 1172 EmitOperand(4, operand);
1087 } 1173 }
1088 1174
1089 1175
1090 void Assembler::jmp(Label* label, bool near) { 1176 void Assembler::jmp(Label* label, bool near) {
(...skipping 14 matching lines...) Expand all
1105 EmitUint8(0xEB); 1191 EmitUint8(0xEB);
1106 EmitNearLabelLink(label); 1192 EmitNearLabelLink(label);
1107 } else { 1193 } else {
1108 EmitUint8(0xE9); 1194 EmitUint8(0xE9);
1109 EmitLabelLink(label); 1195 EmitLabelLink(label);
1110 } 1196 }
1111 } 1197 }
1112 1198
1113 1199
1114 void Assembler::jmp(const ExternalLabel* label) { 1200 void Assembler::jmp(const ExternalLabel* label) {
1115 movq(TMP, Immediate(label->address())); 1201 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1116 jmp(TMP); 1202 intptr_t call_start = buffer_.GetPosition();
1203
1204 // Encode movq(TMP, Immediate(label->address())), but always as imm64.
1205 EmitRegisterREX(TMP, REX_W);
1206 EmitUint8(0xB8 | (TMP & 7));
1207 EmitInt64(label->address());
1208
1209 // Encode jmp(TMP).
1210 Operand operand(TMP);
1211 EmitOperandREX(4, operand, REX_NONE);
1212 EmitUint8(0xFF);
1213 EmitOperand(4, operand);
1214
1215 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize);
1117 } 1216 }
1118 1217
1119 1218
1120 void Assembler::lock() { 1219 void Assembler::lock() {
1121 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1220 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1122 EmitUint8(0xF0); 1221 EmitUint8(0xF0);
1123 } 1222 }
1124 1223
1125 1224
1126 void Assembler::cmpxchgl(const Address& address, Register reg) { 1225 void Assembler::cmpxchgl(const Address& address, Register reg) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1187 if (object.IsSmi()) { 1286 if (object.IsSmi()) {
1188 cmpq(reg, Immediate(reinterpret_cast<int64_t>(object.raw()))); 1287 cmpq(reg, Immediate(reinterpret_cast<int64_t>(object.raw())));
1189 } else { 1288 } else {
1190 ASSERT(reg != TMP); 1289 ASSERT(reg != TMP);
1191 LoadObject(TMP, object); 1290 LoadObject(TMP, object);
1192 cmpq(reg, TMP); 1291 cmpq(reg, TMP);
1193 } 1292 }
1194 } 1293 }
1195 1294
1196 1295
1296 void Assembler::StoreIntoObject(Register object,
1297 const FieldAddress& dest,
1298 Register value) {
1299 // TODO(iposva): Add write barrier.
1300 movq(dest, value);
1301 }
1302
1303
1197 void Assembler::Stop(const char* message) { 1304 void Assembler::Stop(const char* message) {
1198 // Emit the lower half and the higher half of the message address as immediate 1305 // Emit the lower half and the higher half of the message address as immediate
1199 // operands in the test rax instructions, followed by the int3 instruction. 1306 // operands in the test rax instructions, followed by the int3 instruction.
1200 // Execution can be resumed with the 'cont' command in gdb. 1307 // Execution can be resumed with the 'cont' command in gdb.
1201 int64_t message_address = reinterpret_cast<int64_t>(message); 1308 int64_t message_address = reinterpret_cast<int64_t>(message);
1202 testl(RAX, Immediate(Utils::Low32Bits(message_address))); 1309 testl(RAX, Immediate(Utils::Low32Bits(message_address)));
1203 testl(RAX, Immediate(Utils::High32Bits(message_address))); 1310 testl(RAX, Immediate(Utils::High32Bits(message_address)));
1204 int3(); 1311 int3();
1205 } 1312 }
1206 1313
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 entry.CallFromDart(this); 1354 entry.CallFromDart(this);
1248 } 1355 }
1249 1356
1250 1357
1251 void Assembler::CallRuntimeFromStub(const RuntimeEntry& entry) { 1358 void Assembler::CallRuntimeFromStub(const RuntimeEntry& entry) {
1252 entry.CallFromStub(this); 1359 entry.CallFromStub(this);
1253 } 1360 }
1254 1361
1255 1362
1256 void Assembler::Align(int alignment, int offset) { 1363 void Assembler::Align(int alignment, int offset) {
1257 UNIMPLEMENTED(); 1364 ASSERT(Utils::IsPowerOfTwo(alignment));
1365 int pos = offset + buffer_.GetPosition();
1366 int mod = pos & (alignment - 1);
1367 if (mod == 0) {
1368 return;
1369 }
1370 int bytes_needed = alignment - mod;
1371 while (bytes_needed > MAX_NOP_SIZE) {
1372 nop(MAX_NOP_SIZE);
1373 bytes_needed -= MAX_NOP_SIZE;
1374 }
1375 if (bytes_needed) {
1376 nop(bytes_needed);
1377 }
1378 ASSERT(((offset + buffer_.GetPosition()) & (alignment-1)) == 0);
1258 } 1379 }
1259 1380
1260 1381
1261 void Assembler::EmitOperand(int rm, const Operand& operand) { 1382 void Assembler::EmitOperand(int rm, const Operand& operand) {
1262 ASSERT(rm >= 0 && rm < 8); 1383 ASSERT(rm >= 0 && rm < 8);
1263 const int length = operand.length_; 1384 const int length = operand.length_;
1264 ASSERT(length > 0); 1385 ASSERT(length > 0);
1265 // Emit the ModRM byte updated with the given RM value. 1386 // Emit the ModRM byte updated with the given RM value.
1266 ASSERT((operand.encoding_[0] & 0x38) == 0); 1387 ASSERT((operand.encoding_[0] & 0x38) == 0);
1267 EmitUint8(operand.encoding_[0] + (rm << 3)); 1388 EmitUint8(operand.encoding_[0] + (rm << 3));
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 } else { 1491 } else {
1371 EmitRegisterREX(operand, REX_NONE); 1492 EmitRegisterREX(operand, REX_NONE);
1372 } 1493 }
1373 EmitUint8(0xD3); 1494 EmitUint8(0xD3);
1374 EmitOperand(rm, Operand(operand)); 1495 EmitOperand(rm, Operand(operand));
1375 } 1496 }
1376 1497
1377 } // namespace dart 1498 } // namespace dart
1378 1499
1379 #endif // defined TARGET_ARCH_X64 1500 #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