Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 2 // All Rights Reserved. | 2 // All Rights Reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
| 6 // are met: | 6 // are met: |
| 7 // | 7 // |
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
| 10 // | 10 // |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 __ mov(esp, Operand(ebp)); | 115 __ mov(esp, Operand(ebp)); |
| 116 __ pop(ebx); | 116 __ pop(ebx); |
| 117 __ pop(edx); | 117 __ pop(edx); |
| 118 __ pop(ecx); | 118 __ pop(ecx); |
| 119 __ popfd(); | 119 __ popfd(); |
| 120 __ pop(ebp); | 120 __ pop(ebp); |
| 121 __ ret(0); | 121 __ ret(0); |
| 122 #undef __ | 122 #undef __ |
| 123 CodeDesc desc; | 123 CodeDesc desc; |
| 124 assm.GetCode(&desc); | 124 assm.GetCode(&desc); |
| 125 Object* code = Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB)); | 125 Object* code = |
| 126 Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB), NULL); | |
| 126 if (!code->IsCode()) return; | 127 if (!code->IsCode()) return; |
| 127 F0 f = FUNCTION_CAST<F0>(Code::cast(code)->entry()); | 128 F0 f = FUNCTION_CAST<F0>(Code::cast(code)->entry()); |
| 128 uint32_t res = f(); | 129 uint32_t res = f(); |
| 129 supported_ = (res | (1 << CPUID)); | 130 supported_ = (res | (1 << CPUID)); |
| 130 } | 131 } |
| 131 | 132 |
| 132 | 133 |
| 133 // ----------------------------------------------------------------------------- | 134 // ----------------------------------------------------------------------------- |
| 134 // Implementation of Displacement | 135 // Implementation of Displacement |
| 135 | 136 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 287 spare_buffer_ = NULL; | 288 spare_buffer_ = NULL; |
| 288 } | 289 } |
| 289 } | 290 } |
| 290 if (buffer == NULL) { | 291 if (buffer == NULL) { |
| 291 buffer_ = NewArray<byte>(buffer_size); | 292 buffer_ = NewArray<byte>(buffer_size); |
| 292 } else { | 293 } else { |
| 293 buffer_ = static_cast<byte*>(buffer); | 294 buffer_ = static_cast<byte*>(buffer); |
| 294 } | 295 } |
| 295 buffer_size_ = buffer_size; | 296 buffer_size_ = buffer_size; |
| 296 own_buffer_ = true; | 297 own_buffer_ = true; |
| 297 | |
| 298 } else { | 298 } else { |
| 299 // use externally provided buffer instead | 299 // use externally provided buffer instead |
| 300 ASSERT(buffer_size > 0); | 300 ASSERT(buffer_size > 0); |
| 301 buffer_ = static_cast<byte*>(buffer); | 301 buffer_ = static_cast<byte*>(buffer); |
| 302 buffer_size_ = buffer_size; | 302 buffer_size_ = buffer_size; |
| 303 own_buffer_ = false; | 303 own_buffer_ = false; |
| 304 } | 304 } |
| 305 | 305 |
| 306 // Clear the buffer in debug mode unless it was provided by the | 306 // Clear the buffer in debug mode unless it was provided by the |
| 307 // caller in which case we can't be sure it's okay to overwrite | 307 // caller in which case we can't be sure it's okay to overwrite |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 413 | 413 |
| 414 | 414 |
| 415 void Assembler::push(const Operand& src) { | 415 void Assembler::push(const Operand& src) { |
| 416 EnsureSpace ensure_space(this); | 416 EnsureSpace ensure_space(this); |
| 417 last_pc_ = pc_; | 417 last_pc_ = pc_; |
| 418 EMIT(0xFF); | 418 EMIT(0xFF); |
| 419 emit_operand(esi, src); | 419 emit_operand(esi, src); |
| 420 } | 420 } |
| 421 | 421 |
| 422 | 422 |
| 423 void Assembler::push(Label* label, RelocInfo::Mode reloc_mode) { | |
| 424 ASSERT_NOT_NULL(label); | |
| 425 EnsureSpace ensure_space(this); | |
| 426 last_pc_ = pc_; | |
| 427 // If reloc_mode == NONE, the label is stored as buffer relative. | |
| 428 ASSERT(reloc_mode == RelocInfo::NONE); | |
| 429 if (label->is_bound()) { | |
| 430 // Index of position in Code object: | |
| 431 int pos = label->pos() + Code::kHeaderSize; | |
|
Lasse Reichstein
2008/11/25 10:34:46
Known bug: Off-by-one. Must subtract kHeapObjectTa
| |
| 432 if (pos >= 0 && pos < 256) { | |
| 433 EMIT(0x6a); | |
| 434 EMIT(pos); | |
| 435 } else { | |
| 436 EMIT(0x68); | |
| 437 emit(pos); | |
| 438 } | |
| 439 } else { | |
| 440 EMIT(0x68); | |
| 441 emit_disp(label, Displacement::CODE_RELATIVE); | |
| 442 } | |
| 443 } | |
| 444 | |
| 445 | |
| 423 void Assembler::pop(Register dst) { | 446 void Assembler::pop(Register dst) { |
| 424 ASSERT(reloc_info_writer.last_pc() != NULL); | 447 ASSERT(reloc_info_writer.last_pc() != NULL); |
| 425 if (FLAG_push_pop_elimination && (reloc_info_writer.last_pc() <= last_pc_)) { | 448 if (FLAG_push_pop_elimination && (reloc_info_writer.last_pc() <= last_pc_)) { |
| 426 // (last_pc_ != NULL) is rolled into the above check | 449 // (last_pc_ != NULL) is rolled into the above check |
| 427 // If a last_pc_ is set, we need to make sure that there has not been any | 450 // If a last_pc_ is set, we need to make sure that there has not been any |
| 428 // relocation information generated between the last instruction and this | 451 // relocation information generated between the last instruction and this |
| 429 // pop instruction. | 452 // pop instruction. |
| 430 byte instr = last_pc_[0]; | 453 byte instr = last_pc_[0]; |
| 431 if ((instr & ~0x7) == 0x50) { | 454 if ((instr & ~0x7) == 0x50) { |
| 432 int push_reg_code = instr & 0x7; | 455 int push_reg_code = instr & 0x7; |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 539 | 562 |
| 540 | 563 |
| 541 void Assembler::pop(const Operand& dst) { | 564 void Assembler::pop(const Operand& dst) { |
| 542 EnsureSpace ensure_space(this); | 565 EnsureSpace ensure_space(this); |
| 543 last_pc_ = pc_; | 566 last_pc_ = pc_; |
| 544 EMIT(0x8F); | 567 EMIT(0x8F); |
| 545 emit_operand(eax, dst); | 568 emit_operand(eax, dst); |
| 546 } | 569 } |
| 547 | 570 |
| 548 | 571 |
| 572 void Assembler::enter(const Immediate& size) { | |
| 573 EnsureSpace ensure_space(this); | |
| 574 last_pc_ = pc_; | |
| 575 EMIT(0xC8); | |
| 576 emit_w(size); | |
| 577 EMIT(0); | |
| 578 } | |
| 579 | |
| 580 | |
| 581 void Assembler::leave() { | |
| 582 EnsureSpace ensure_space(this); | |
| 583 last_pc_ = pc_; | |
| 584 EMIT(0xC9); | |
| 585 } | |
| 586 | |
| 587 | |
| 549 void Assembler::mov_b(Register dst, const Operand& src) { | 588 void Assembler::mov_b(Register dst, const Operand& src) { |
| 550 EnsureSpace ensure_space(this); | 589 EnsureSpace ensure_space(this); |
| 551 last_pc_ = pc_; | 590 last_pc_ = pc_; |
| 552 EMIT(0x8A); | 591 EMIT(0x8A); |
| 553 emit_operand(dst, src); | 592 emit_operand(dst, src); |
| 554 } | 593 } |
| 555 | 594 |
| 556 | 595 |
| 557 void Assembler::mov_b(const Operand& dst, int8_t imm8) { | 596 void Assembler::mov_b(const Operand& dst, int8_t imm8) { |
| 558 EnsureSpace ensure_space(this); | 597 EnsureSpace ensure_space(this); |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 823 } | 862 } |
| 824 | 863 |
| 825 | 864 |
| 826 void Assembler::cmp(const Operand& op, const Immediate& imm) { | 865 void Assembler::cmp(const Operand& op, const Immediate& imm) { |
| 827 EnsureSpace ensure_space(this); | 866 EnsureSpace ensure_space(this); |
| 828 last_pc_ = pc_; | 867 last_pc_ = pc_; |
| 829 emit_arith(7, op, imm); | 868 emit_arith(7, op, imm); |
| 830 } | 869 } |
| 831 | 870 |
| 832 | 871 |
| 872 void Assembler::rep_cmpsb() { | |
|
Lasse Reichstein
2008/11/25 10:34:46
Should this be split into cld, rep and cmpsb? The
| |
| 873 EnsureSpace ensure_space(this); | |
| 874 last_pc_ = pc_; | |
| 875 EMIT(0xFC); // CLD to ensure forward operation | |
| 876 EMIT(0xF3); // REP | |
| 877 EMIT(0xA6); // CMPSB | |
| 878 } | |
| 879 | |
| 880 void Assembler::rep_cmpsw() { | |
| 881 EnsureSpace ensure_space(this); | |
| 882 last_pc_ = pc_; | |
| 883 EMIT(0xFC); // CLD to ensure forward operation | |
| 884 EMIT(0xF3); // REP | |
| 885 EMIT(0xA7); // CMPSW | |
| 886 } | |
| 887 | |
| 888 | |
| 833 void Assembler::dec_b(Register dst) { | 889 void Assembler::dec_b(Register dst) { |
| 834 EnsureSpace ensure_space(this); | 890 EnsureSpace ensure_space(this); |
| 835 last_pc_ = pc_; | 891 last_pc_ = pc_; |
| 836 EMIT(0xFE); | 892 EMIT(0xFE); |
| 837 EMIT(0xC8 | dst.code()); | 893 EMIT(0xC8 | dst.code()); |
| 838 } | 894 } |
| 839 | 895 |
| 840 | 896 |
| 841 void Assembler::dec(Register dst) { | 897 void Assembler::dec(Register dst) { |
| 842 EnsureSpace ensure_space(this); | 898 EnsureSpace ensure_space(this); |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1067 | 1123 |
| 1068 | 1124 |
| 1069 void Assembler::shr(Register dst) { | 1125 void Assembler::shr(Register dst) { |
| 1070 EnsureSpace ensure_space(this); | 1126 EnsureSpace ensure_space(this); |
| 1071 last_pc_ = pc_; | 1127 last_pc_ = pc_; |
| 1072 EMIT(0xD3); | 1128 EMIT(0xD3); |
| 1073 EMIT(0xE8 | dst.code()); | 1129 EMIT(0xE8 | dst.code()); |
| 1074 } | 1130 } |
| 1075 | 1131 |
| 1076 | 1132 |
| 1133 void Assembler::shr_cl(Register dst) { | |
| 1134 EnsureSpace ensure_space(this); | |
| 1135 last_pc_ = pc_; | |
| 1136 EMIT(0xD1); | |
| 1137 EMIT(0xE8 | dst.code()); | |
| 1138 } | |
| 1139 | |
| 1140 | |
| 1077 void Assembler::sub(const Operand& dst, const Immediate& x) { | 1141 void Assembler::sub(const Operand& dst, const Immediate& x) { |
| 1078 EnsureSpace ensure_space(this); | 1142 EnsureSpace ensure_space(this); |
| 1079 last_pc_ = pc_; | 1143 last_pc_ = pc_; |
| 1080 emit_arith(5, dst, x); | 1144 emit_arith(5, dst, x); |
| 1081 } | 1145 } |
| 1082 | 1146 |
| 1083 | 1147 |
| 1084 void Assembler::sub(Register dst, const Operand& src) { | 1148 void Assembler::sub(Register dst, const Operand& src) { |
| 1085 EnsureSpace ensure_space(this); | 1149 EnsureSpace ensure_space(this); |
| 1086 last_pc_ = pc_; | 1150 last_pc_ = pc_; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1164 } | 1228 } |
| 1165 | 1229 |
| 1166 | 1230 |
| 1167 void Assembler::xor_(const Operand& dst, const Immediate& x) { | 1231 void Assembler::xor_(const Operand& dst, const Immediate& x) { |
| 1168 EnsureSpace ensure_space(this); | 1232 EnsureSpace ensure_space(this); |
| 1169 last_pc_ = pc_; | 1233 last_pc_ = pc_; |
| 1170 emit_arith(6, dst, x); | 1234 emit_arith(6, dst, x); |
| 1171 } | 1235 } |
| 1172 | 1236 |
| 1173 | 1237 |
| 1238 void Assembler::bt(const Operand& dst, Register src) { | |
| 1239 EnsureSpace ensure_space(this); | |
| 1240 last_pc_ = pc_; | |
| 1241 EMIT(0x0F); | |
| 1242 EMIT(0xA3); | |
| 1243 emit_operand(src, dst); | |
| 1244 } | |
| 1245 | |
| 1246 | |
| 1174 void Assembler::bts(const Operand& dst, Register src) { | 1247 void Assembler::bts(const Operand& dst, Register src) { |
| 1175 EnsureSpace ensure_space(this); | 1248 EnsureSpace ensure_space(this); |
| 1176 last_pc_ = pc_; | 1249 last_pc_ = pc_; |
| 1177 EMIT(0x0F); | 1250 EMIT(0x0F); |
| 1178 EMIT(0xAB); | 1251 EMIT(0xAB); |
| 1179 emit_operand(src, dst); | 1252 emit_operand(src, dst); |
| 1180 } | 1253 } |
| 1181 | 1254 |
| 1182 | 1255 |
| 1183 void Assembler::hlt() { | 1256 void Assembler::hlt() { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1217 if (imm16 == 0) { | 1290 if (imm16 == 0) { |
| 1218 EMIT(0xC3); | 1291 EMIT(0xC3); |
| 1219 } else { | 1292 } else { |
| 1220 EMIT(0xC2); | 1293 EMIT(0xC2); |
| 1221 EMIT(imm16 & 0xFF); | 1294 EMIT(imm16 & 0xFF); |
| 1222 EMIT((imm16 >> 8) & 0xFF); | 1295 EMIT((imm16 >> 8) & 0xFF); |
| 1223 } | 1296 } |
| 1224 } | 1297 } |
| 1225 | 1298 |
| 1226 | 1299 |
| 1227 void Assembler::leave() { | |
| 1228 EnsureSpace ensure_space(this); | |
| 1229 last_pc_ = pc_; | |
| 1230 EMIT(0xC9); | |
| 1231 } | |
| 1232 | |
| 1233 | |
| 1234 // Labels refer to positions in the (to be) generated code. | 1300 // Labels refer to positions in the (to be) generated code. |
| 1235 // There are bound, linked, and unused labels. | 1301 // There are bound, linked, and unused labels. |
| 1236 // | 1302 // |
| 1237 // Bound labels refer to known positions in the already | 1303 // Bound labels refer to known positions in the already |
| 1238 // generated code. pos() is the position the label refers to. | 1304 // generated code. pos() is the position the label refers to. |
| 1239 // | 1305 // |
| 1240 // Linked labels refer to unknown positions in the code | 1306 // Linked labels refer to unknown positions in the code |
| 1241 // to be generated; pos() is the position of the 32bit | 1307 // to be generated; pos() is the position of the 32bit |
| 1242 // Displacement of the last instruction using the label. | 1308 // Displacement of the last instruction using the label. |
| 1243 | 1309 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1263 } | 1329 } |
| 1264 | 1330 |
| 1265 | 1331 |
| 1266 void Assembler::bind_to(Label* L, int pos) { | 1332 void Assembler::bind_to(Label* L, int pos) { |
| 1267 EnsureSpace ensure_space(this); | 1333 EnsureSpace ensure_space(this); |
| 1268 last_pc_ = NULL; | 1334 last_pc_ = NULL; |
| 1269 ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position | 1335 ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position |
| 1270 while (L->is_linked()) { | 1336 while (L->is_linked()) { |
| 1271 Displacement disp = disp_at(L); | 1337 Displacement disp = disp_at(L); |
| 1272 int fixup_pos = L->pos(); | 1338 int fixup_pos = L->pos(); |
| 1273 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) { | 1339 if (disp.type() == Displacement::CODE_RELATIVE) { |
| 1274 ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected | 1340 long_at_put(fixup_pos, pos + Code::kHeaderSize); |
|
Lasse Reichstein
2008/11/25 10:34:46
Off-by-one here too.
| |
| 1341 } else { | |
| 1342 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) { | |
| 1343 ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected | |
| 1344 } | |
| 1345 // relative address, relative to point after address | |
| 1346 int imm32 = pos - (fixup_pos + sizeof(int32_t)); | |
| 1347 long_at_put(fixup_pos, imm32); | |
| 1275 } | 1348 } |
| 1276 // relative address, relative to point after address | |
| 1277 int imm32 = pos - (fixup_pos + sizeof(int32_t)); | |
| 1278 long_at_put(fixup_pos, imm32); | |
| 1279 disp.next(L); | 1349 disp.next(L); |
| 1280 } | 1350 } |
| 1281 L->bind_to(pos); | 1351 L->bind_to(pos); |
| 1282 } | 1352 } |
| 1283 | 1353 |
| 1284 | 1354 |
| 1285 void Assembler::link_to(Label* L, Label* appendix) { | 1355 void Assembler::link_to(Label* L, Label* appendix) { |
| 1286 EnsureSpace ensure_space(this); | 1356 EnsureSpace ensure_space(this); |
| 1287 last_pc_ = NULL; | 1357 last_pc_ = NULL; |
| 1288 if (appendix->is_linked()) { | 1358 if (appendix->is_linked()) { |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2064 ASSERT(bound_label.is_bound()); | 2134 ASSERT(bound_label.is_bound()); |
| 2065 ASSERT(0 <= position); | 2135 ASSERT(0 <= position); |
| 2066 ASSERT(position + static_cast<int>(sizeof(uint32_t)) <= pc_offset()); | 2136 ASSERT(position + static_cast<int>(sizeof(uint32_t)) <= pc_offset()); |
| 2067 ASSERT(long_at(position) == 0); // only initialize once! | 2137 ASSERT(long_at(position) == 0); // only initialize once! |
| 2068 | 2138 |
| 2069 uint32_t label_loc = reinterpret_cast<uint32_t>(addr_at(bound_label.pos())); | 2139 uint32_t label_loc = reinterpret_cast<uint32_t>(addr_at(bound_label.pos())); |
| 2070 long_at_put(position, label_loc); | 2140 long_at_put(position, label_loc); |
| 2071 } | 2141 } |
| 2072 | 2142 |
| 2073 } } // namespace v8::internal | 2143 } } // namespace v8::internal |
| OLD | NEW |