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

Side by Side Diff: src/ia32/assembler-ia32.cc

Issue 8139027: Version 3.6.5 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: '' Created 9 years, 2 months 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 | « src/ia32/assembler-ia32.h ('k') | src/ia32/assembler-ia32-inl.h » ('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) 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
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 11 matching lines...) Expand all
79 } 81 }
80 82
81 Assembler assm(NULL, memory->address(), kBufferSize); 83 Assembler assm(NULL, memory->address(), kBufferSize);
82 Label cpuid, done; 84 Label cpuid, done;
83 #define __ assm. 85 #define __ assm.
84 // Save old esp, since we are going to modify the stack. 86 // Save old esp, since we are going to modify the stack.
85 __ push(ebp); 87 __ push(ebp);
86 __ pushfd(); 88 __ pushfd();
87 __ push(ecx); 89 __ push(ecx);
88 __ push(ebx); 90 __ push(ebx);
89 __ mov(ebp, Operand(esp)); 91 __ mov(ebp, esp);
90 92
91 // If we can modify bit 21 of the EFLAGS register, then CPUID is supported. 93 // If we can modify bit 21 of the EFLAGS register, then CPUID is supported.
92 __ pushfd(); 94 __ pushfd();
93 __ pop(eax); 95 __ pop(eax);
94 __ mov(edx, Operand(eax)); 96 __ mov(edx, eax);
95 __ xor_(eax, 0x200000); // Flip bit 21. 97 __ xor_(eax, 0x200000); // Flip bit 21.
96 __ push(eax); 98 __ push(eax);
97 __ popfd(); 99 __ popfd();
98 __ pushfd(); 100 __ pushfd();
99 __ pop(eax); 101 __ pop(eax);
100 __ xor_(eax, Operand(edx)); // Different if CPUID is supported. 102 __ xor_(eax, edx); // Different if CPUID is supported.
101 __ j(not_zero, &cpuid); 103 __ j(not_zero, &cpuid);
102 104
103 // CPUID not supported. Clear the supported features in edx:eax. 105 // CPUID not supported. Clear the supported features in edx:eax.
104 __ xor_(eax, Operand(eax)); 106 __ xor_(eax, eax);
105 __ xor_(edx, Operand(edx)); 107 __ xor_(edx, edx);
106 __ jmp(&done); 108 __ jmp(&done);
107 109
108 // Invoke CPUID with 1 in eax to get feature information in 110 // Invoke CPUID with 1 in eax to get feature information in
109 // ecx:edx. Temporarily enable CPUID support because we know it's 111 // ecx:edx. Temporarily enable CPUID support because we know it's
110 // safe here. 112 // safe here.
111 __ bind(&cpuid); 113 __ bind(&cpuid);
112 __ mov(eax, 1); 114 __ mov(eax, 1);
113 supported_ = (1 << CPUID); 115 supported_ = (1 << CPUID);
114 { Scope fscope(CPUID); 116 { Scope fscope(CPUID);
115 __ cpuid(); 117 __ cpuid();
116 } 118 }
117 supported_ = 0; 119 supported_ = 0;
118 120
119 // Move the result from ecx:edx to edx:eax and make sure to mark the 121 // Move the result from ecx:edx to edx:eax and make sure to mark the
120 // CPUID feature as supported. 122 // CPUID feature as supported.
121 __ mov(eax, Operand(edx)); 123 __ mov(eax, edx);
122 __ or_(eax, 1 << CPUID); 124 __ or_(eax, 1 << CPUID);
123 __ mov(edx, Operand(ecx)); 125 __ mov(edx, ecx);
124 126
125 // Done. 127 // Done.
126 __ bind(&done); 128 __ bind(&done);
127 __ mov(esp, Operand(ebp)); 129 __ mov(esp, ebp);
128 __ pop(ebx); 130 __ pop(ebx);
129 __ pop(ecx); 131 __ pop(ecx);
130 __ popfd(); 132 __ popfd();
131 __ pop(ebp); 133 __ pop(ebp);
132 __ ret(0); 134 __ ret(0);
133 #undef __ 135 #undef __
134 136
135 typedef uint64_t (*F0)(); 137 typedef uint64_t (*F0)();
136 F0 probe = FUNCTION_CAST<F0>(reinterpret_cast<Address>(memory->address())); 138 F0 probe = FUNCTION_CAST<F0>(reinterpret_cast<Address>(memory->address()));
137 supported_ = probe(); 139 supported_ = probe();
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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& op, Register reg) {
751 ASSERT(src.is_byte_register()); 776 ASSERT(reg.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(reg, op);
755 } 780 }
756 781
757 782
758 void Assembler::cmpb(Register dst, const Operand& src) { 783 void Assembler::cmpb(Register reg, const Operand& op) {
759 ASSERT(dst.is_byte_register()); 784 ASSERT(reg.is_byte_register());
760 EnsureSpace ensure_space(this); 785 EnsureSpace ensure_space(this);
761 EMIT(0x3A); 786 EMIT(0x3A);
762 emit_operand(dst, src); 787 emit_operand(reg, op);
763 } 788 }
764 789
765 790
766 void Assembler::cmpw(const Operand& op, Immediate imm16) { 791 void Assembler::cmpw(const Operand& op, Immediate imm16) {
767 ASSERT(imm16.is_int16()); 792 ASSERT(imm16.is_int16());
768 EnsureSpace ensure_space(this); 793 EnsureSpace ensure_space(this);
769 EMIT(0x66); 794 EMIT(0x66);
770 EMIT(0x81); 795 EMIT(0x81);
771 emit_operand(edi, op); 796 emit_operand(edi, op);
772 emit_w(imm16); 797 emit_w(imm16);
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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));
1171 } 1180 }
1172 1181
1173 1182
1174 void Assembler::xor_(Register dst, const Operand& src) { 1183 void Assembler::xor_(Register dst, const Operand& src) {
1175 EnsureSpace ensure_space(this); 1184 EnsureSpace ensure_space(this);
1176 EMIT(0x33); 1185 EMIT(0x33);
1177 emit_operand(dst, src); 1186 emit_operand(dst, src);
1178 } 1187 }
1179 1188
1180 1189
1181 void Assembler::xor_(const Operand& src, Register dst) { 1190 void Assembler::xor_(const Operand& dst, Register src) {
1182 EnsureSpace ensure_space(this); 1191 EnsureSpace ensure_space(this);
1183 EMIT(0x31); 1192 EMIT(0x31);
1184 emit_operand(dst, src); 1193 emit_operand(src, dst);
1185 } 1194 }
1186 1195
1187 1196
1188 void Assembler::xor_(const Operand& dst, const Immediate& x) { 1197 void Assembler::xor_(const Operand& dst, const Immediate& x) {
1189 EnsureSpace ensure_space(this); 1198 EnsureSpace ensure_space(this);
1190 emit_arith(6, dst, x); 1199 emit_arith(6, dst, x);
1191 } 1200 }
1192 1201
1193 1202
1194 void Assembler::bt(const Operand& dst, Register src) { 1203 void Assembler::bt(const Operand& dst, Register src) {
(...skipping 1269 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
OLDNEW
« no previous file with comments | « src/ia32/assembler-ia32.h ('k') | src/ia32/assembler-ia32-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698