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 |