| 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 // ----------------------------------------------------------------------------- | 48 // ----------------------------------------------------------------------------- |
| 49 // Implementation of CpuFeatures | 49 // Implementation of CpuFeatures |
| 50 | 50 |
| 51 #ifdef DEBUG | 51 #ifdef DEBUG |
| 52 bool CpuFeatures::initialized_ = false; | 52 bool CpuFeatures::initialized_ = false; |
| 53 #endif | 53 #endif |
| 54 uint64_t CpuFeatures::supported_ = 0; | 54 uint64_t CpuFeatures::supported_ = 0; |
| 55 uint64_t CpuFeatures::found_by_runtime_probing_ = 0; | 55 uint64_t CpuFeatures::found_by_runtime_probing_ = 0; |
| 56 | 56 |
| 57 | 57 |
| 58 // The Probe method needs executable memory, so it uses Heap::CreateCode. |
| 59 // Allocation failure is silent and leads to safe default. |
| 58 void CpuFeatures::Probe() { | 60 void CpuFeatures::Probe() { |
| 59 ASSERT(!initialized_); | 61 ASSERT(!initialized_); |
| 60 ASSERT(supported_ == 0); | 62 ASSERT(supported_ == 0); |
| 61 #ifdef DEBUG | 63 #ifdef DEBUG |
| 62 initialized_ = true; | 64 initialized_ = true; |
| 63 #endif | 65 #endif |
| 64 if (Serializer::enabled()) { | 66 if (Serializer::enabled()) { |
| 65 supported_ |= OS::CpuFeaturesImpliedByPlatform(); | 67 supported_ |= OS::CpuFeaturesImpliedByPlatform(); |
| 66 return; // No features if we might serialize. | 68 return; // No features if we might serialize. |
| 67 } | 69 } |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 set_sib(scale, index, ebp); | 281 set_sib(scale, index, ebp); |
| 280 set_dispr(disp, rmode); | 282 set_dispr(disp, rmode); |
| 281 } | 283 } |
| 282 | 284 |
| 283 | 285 |
| 284 bool Operand::is_reg(Register reg) const { | 286 bool Operand::is_reg(Register reg) const { |
| 285 return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only. | 287 return ((buf_[0] & 0xF8) == 0xC0) // addressing mode is register only. |
| 286 && ((buf_[0] & 0x07) == reg.code()); // register codes match. | 288 && ((buf_[0] & 0x07) == reg.code()); // register codes match. |
| 287 } | 289 } |
| 288 | 290 |
| 291 |
| 292 bool Operand::is_reg_only() const { |
| 293 return (buf_[0] & 0xF8) == 0xC0; // Addressing mode is register only. |
| 294 } |
| 295 |
| 296 |
| 297 Register Operand::reg() const { |
| 298 ASSERT(is_reg_only()); |
| 299 return Register::from_code(buf_[0] & 0x07); |
| 300 } |
| 301 |
| 302 |
| 289 // ----------------------------------------------------------------------------- | 303 // ----------------------------------------------------------------------------- |
| 290 // Implementation of Assembler. | 304 // Implementation of Assembler. |
| 291 | 305 |
| 292 // Emit a single byte. Must always be inlined. | 306 // Emit a single byte. Must always be inlined. |
| 293 #define EMIT(x) \ | 307 #define EMIT(x) \ |
| 294 *pc_++ = (x) | 308 *pc_++ = (x) |
| 295 | 309 |
| 296 | 310 |
| 297 #ifdef GENERATED_CODE_COVERAGE | 311 #ifdef GENERATED_CODE_COVERAGE |
| 298 static void InitCoverageLog(); | 312 static void InitCoverageLog(); |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 } | 708 } |
| 695 | 709 |
| 696 | 710 |
| 697 void Assembler::add(Register dst, const Operand& src) { | 711 void Assembler::add(Register dst, const Operand& src) { |
| 698 EnsureSpace ensure_space(this); | 712 EnsureSpace ensure_space(this); |
| 699 EMIT(0x03); | 713 EMIT(0x03); |
| 700 emit_operand(dst, src); | 714 emit_operand(dst, src); |
| 701 } | 715 } |
| 702 | 716 |
| 703 | 717 |
| 718 void Assembler::add(const Operand& dst, Register src) { |
| 719 EnsureSpace ensure_space(this); |
| 720 EMIT(0x01); |
| 721 emit_operand(src, dst); |
| 722 } |
| 723 |
| 724 |
| 704 void Assembler::add(const Operand& dst, const Immediate& x) { | 725 void Assembler::add(const Operand& dst, const Immediate& x) { |
| 705 ASSERT(reloc_info_writer.last_pc() != NULL); | 726 ASSERT(reloc_info_writer.last_pc() != NULL); |
| 706 EnsureSpace ensure_space(this); | 727 EnsureSpace ensure_space(this); |
| 707 emit_arith(0, dst, x); | 728 emit_arith(0, dst, x); |
| 708 } | 729 } |
| 709 | 730 |
| 710 | 731 |
| 711 void Assembler::and_(Register dst, int32_t imm32) { | 732 void Assembler::and_(Register dst, int32_t imm32) { |
| 712 and_(dst, Immediate(imm32)); | 733 and_(dst, Immediate(imm32)); |
| 713 } | 734 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 734 | 755 |
| 735 void Assembler::and_(const Operand& dst, Register src) { | 756 void Assembler::and_(const Operand& dst, Register src) { |
| 736 EnsureSpace ensure_space(this); | 757 EnsureSpace ensure_space(this); |
| 737 EMIT(0x21); | 758 EMIT(0x21); |
| 738 emit_operand(src, dst); | 759 emit_operand(src, dst); |
| 739 } | 760 } |
| 740 | 761 |
| 741 | 762 |
| 742 void Assembler::cmpb(const Operand& op, int8_t imm8) { | 763 void Assembler::cmpb(const Operand& op, int8_t imm8) { |
| 743 EnsureSpace ensure_space(this); | 764 EnsureSpace ensure_space(this); |
| 744 EMIT(0x80); | 765 if (op.is_reg(eax)) { |
| 745 emit_operand(edi, op); // edi == 7 | 766 EMIT(0x3C); |
| 767 } else { |
| 768 EMIT(0x80); |
| 769 emit_operand(edi, op); // edi == 7 |
| 770 } |
| 746 EMIT(imm8); | 771 EMIT(imm8); |
| 747 } | 772 } |
| 748 | 773 |
| 749 | 774 |
| 750 void Assembler::cmpb(const Operand& dst, Register src) { | 775 void Assembler::cmpb(const Operand& dst, Register src) { |
| 751 ASSERT(src.is_byte_register()); | 776 ASSERT(src.is_byte_register()); |
| 752 EnsureSpace ensure_space(this); | 777 EnsureSpace ensure_space(this); |
| 753 EMIT(0x38); | 778 EMIT(0x38); |
| 754 emit_operand(src, dst); | 779 emit_operand(src, dst); |
| 755 } | 780 } |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1062 } | 1087 } |
| 1063 | 1088 |
| 1064 | 1089 |
| 1065 void Assembler::shr_cl(Register dst) { | 1090 void Assembler::shr_cl(Register dst) { |
| 1066 EnsureSpace ensure_space(this); | 1091 EnsureSpace ensure_space(this); |
| 1067 EMIT(0xD3); | 1092 EMIT(0xD3); |
| 1068 EMIT(0xE8 | dst.code()); | 1093 EMIT(0xE8 | dst.code()); |
| 1069 } | 1094 } |
| 1070 | 1095 |
| 1071 | 1096 |
| 1072 void Assembler::subb(const Operand& op, int8_t imm8) { | |
| 1073 EnsureSpace ensure_space(this); | |
| 1074 if (op.is_reg(eax)) { | |
| 1075 EMIT(0x2c); | |
| 1076 } else { | |
| 1077 EMIT(0x80); | |
| 1078 emit_operand(ebp, op); // ebp == 5 | |
| 1079 } | |
| 1080 EMIT(imm8); | |
| 1081 } | |
| 1082 | |
| 1083 | |
| 1084 void Assembler::sub(const Operand& dst, const Immediate& x) { | 1097 void Assembler::sub(const Operand& dst, const Immediate& x) { |
| 1085 EnsureSpace ensure_space(this); | 1098 EnsureSpace ensure_space(this); |
| 1086 emit_arith(5, dst, x); | 1099 emit_arith(5, dst, x); |
| 1087 } | 1100 } |
| 1088 | 1101 |
| 1089 | 1102 |
| 1090 void Assembler::sub(Register dst, const Operand& src) { | 1103 void Assembler::sub(Register dst, const Operand& src) { |
| 1091 EnsureSpace ensure_space(this); | 1104 EnsureSpace ensure_space(this); |
| 1092 EMIT(0x2B); | 1105 EMIT(0x2B); |
| 1093 emit_operand(dst, src); | 1106 emit_operand(dst, src); |
| 1094 } | 1107 } |
| 1095 | 1108 |
| 1096 | 1109 |
| 1097 void Assembler::subb(Register dst, const Operand& src) { | |
| 1098 ASSERT(dst.code() < 4); | |
| 1099 EnsureSpace ensure_space(this); | |
| 1100 EMIT(0x2A); | |
| 1101 emit_operand(dst, src); | |
| 1102 } | |
| 1103 | |
| 1104 | |
| 1105 void Assembler::sub(const Operand& dst, Register src) { | 1110 void Assembler::sub(const Operand& dst, Register src) { |
| 1106 EnsureSpace ensure_space(this); | 1111 EnsureSpace ensure_space(this); |
| 1107 EMIT(0x29); | 1112 EMIT(0x29); |
| 1108 emit_operand(src, dst); | 1113 emit_operand(src, dst); |
| 1109 } | 1114 } |
| 1110 | 1115 |
| 1111 | 1116 |
| 1112 void Assembler::test(Register reg, const Immediate& imm) { | 1117 void Assembler::test(Register reg, const Immediate& imm) { |
| 1113 EnsureSpace ensure_space(this); | 1118 EnsureSpace ensure_space(this); |
| 1114 // Only use test against byte for registers that have a byte | 1119 // Only use test against byte for registers that have a byte |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1151 | 1156 |
| 1152 void Assembler::test(const Operand& op, const Immediate& imm) { | 1157 void Assembler::test(const Operand& op, const Immediate& imm) { |
| 1153 EnsureSpace ensure_space(this); | 1158 EnsureSpace ensure_space(this); |
| 1154 EMIT(0xF7); | 1159 EMIT(0xF7); |
| 1155 emit_operand(eax, op); | 1160 emit_operand(eax, op); |
| 1156 emit(imm); | 1161 emit(imm); |
| 1157 } | 1162 } |
| 1158 | 1163 |
| 1159 | 1164 |
| 1160 void Assembler::test_b(const Operand& op, uint8_t imm8) { | 1165 void Assembler::test_b(const Operand& op, uint8_t imm8) { |
| 1166 if (op.is_reg_only() && op.reg().code() >= 4) { |
| 1167 test(op, Immediate(imm8)); |
| 1168 return; |
| 1169 } |
| 1161 EnsureSpace ensure_space(this); | 1170 EnsureSpace ensure_space(this); |
| 1162 EMIT(0xF6); | 1171 EMIT(0xF6); |
| 1163 emit_operand(eax, op); | 1172 emit_operand(eax, op); |
| 1164 EMIT(imm8); | 1173 EMIT(imm8); |
| 1165 } | 1174 } |
| 1166 | 1175 |
| 1167 | 1176 |
| 1168 void Assembler::xor_(Register dst, int32_t imm32) { | 1177 void Assembler::xor_(Register dst, int32_t imm32) { |
| 1169 EnsureSpace ensure_space(this); | 1178 EnsureSpace ensure_space(this); |
| 1170 emit_arith(6, Operand(dst), Immediate(imm32)); | 1179 emit_arith(6, Operand(dst), Immediate(imm32)); |
| (...skipping 1293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2464 if (rmode == RelocInfo::EXTERNAL_REFERENCE) { | 2473 if (rmode == RelocInfo::EXTERNAL_REFERENCE) { |
| 2465 #ifdef DEBUG | 2474 #ifdef DEBUG |
| 2466 if (!Serializer::enabled()) { | 2475 if (!Serializer::enabled()) { |
| 2467 Serializer::TooLateToEnableNow(); | 2476 Serializer::TooLateToEnableNow(); |
| 2468 } | 2477 } |
| 2469 #endif | 2478 #endif |
| 2470 if (!Serializer::enabled() && !emit_debug_code()) { | 2479 if (!Serializer::enabled() && !emit_debug_code()) { |
| 2471 return; | 2480 return; |
| 2472 } | 2481 } |
| 2473 } | 2482 } |
| 2474 RelocInfo rinfo(pc_, rmode, data); | 2483 RelocInfo rinfo(pc_, rmode, data, NULL); |
| 2475 reloc_info_writer.Write(&rinfo); | 2484 reloc_info_writer.Write(&rinfo); |
| 2476 } | 2485 } |
| 2477 | 2486 |
| 2478 | 2487 |
| 2479 #ifdef GENERATED_CODE_COVERAGE | 2488 #ifdef GENERATED_CODE_COVERAGE |
| 2480 static FILE* coverage_log = NULL; | 2489 static FILE* coverage_log = NULL; |
| 2481 | 2490 |
| 2482 | 2491 |
| 2483 static void InitCoverageLog() { | 2492 static void InitCoverageLog() { |
| 2484 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG"); | 2493 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG"); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2497 fprintf(coverage_log, "%s\n", file_line); | 2506 fprintf(coverage_log, "%s\n", file_line); |
| 2498 fflush(coverage_log); | 2507 fflush(coverage_log); |
| 2499 } | 2508 } |
| 2500 } | 2509 } |
| 2501 | 2510 |
| 2502 #endif | 2511 #endif |
| 2503 | 2512 |
| 2504 } } // namespace v8::internal | 2513 } } // namespace v8::internal |
| 2505 | 2514 |
| 2506 #endif // V8_TARGET_ARCH_IA32 | 2515 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |