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 |