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

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

Issue 1320006: Updates and fixes for MIPS support. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 7 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
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 are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // 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 24 matching lines...) Expand all
35 35
36 #include "v8.h" 36 #include "v8.h"
37 #include "mips/assembler-mips-inl.h" 37 #include "mips/assembler-mips-inl.h"
38 #include "serialize.h" 38 #include "serialize.h"
39 39
40 40
41 namespace v8 { 41 namespace v8 {
42 namespace internal { 42 namespace internal {
43 43
44 44
45 // Safe default is no features.
46 unsigned CpuFeatures::supported_ = 0;
47 unsigned CpuFeatures::enabled_ = 0;
48 unsigned CpuFeatures::found_by_runtime_probing_ = 0;
49
50 void CpuFeatures::Probe() {
51 // If the compiler is allowed to use fpu then we can use fpu too in our
52 // code generation.
53 #if !defined(__mips__)
54 // For the simulator=mips build, use FPU when FLAG_enable_fpu is enabled.
55 if (FLAG_enable_fpu) {
56 supported_ |= 1u << FPU;
Søren Thygesen Gjesse 2010/05/25 09:00:56 Only 2 space indent.
57 }
58 #else
59 if (Serializer::enabled()) {
60 supported_ |= OS::CpuFeaturesImpliedByPlatform();
61 return; // No features if we might serialize.
62 }
63
64 if (OS::MipsCpuHasFeature(FPU)) {
65 // This implementation also sets the FPU flags if
66 // runtime detection of FPU returns true.
67 supported_ |= 1u << FPU;
68 found_by_runtime_probing_ |= 1u << FPU;
69 }
70 #endif
71 }
72
45 73
46 const Register no_reg = { -1 }; 74 const Register no_reg = { -1 };
47 75
48 const Register zero_reg = { 0 }; 76 const Register zero_reg = { 0 };
49 const Register at = { 1 }; 77 const Register at = { 1 };
50 const Register v0 = { 2 }; 78 const Register v0 = { 2 };
51 const Register v1 = { 3 }; 79 const Register v1 = { 3 };
52 const Register a0 = { 4 }; 80 const Register a0 = { 4 };
53 const Register a1 = { 5 }; 81 const Register a1 = { 5 };
54 const Register a2 = { 6 }; 82 const Register a2 = { 6 };
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 uint16_t sa, 488 uint16_t sa,
461 SecondaryField func) { 489 SecondaryField func) {
462 ASSERT(rd.is_valid() && rs.is_valid() && rt.is_valid() && is_uint5(sa)); 490 ASSERT(rd.is_valid() && rs.is_valid() && rt.is_valid() && is_uint5(sa));
463 Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift) 491 Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
464 | (rd.code() << kRdShift) | (sa << kSaShift) | func; 492 | (rd.code() << kRdShift) | (sa << kSaShift) | func;
465 emit(instr); 493 emit(instr);
466 } 494 }
467 495
468 496
469 void Assembler::GenInstrRegister(Opcode opcode, 497 void Assembler::GenInstrRegister(Opcode opcode,
498 Register rs,
499 Register rt,
500 uint16_t msb,
501 uint16_t lsb,
502 SecondaryField func) {
503 ASSERT(rs.is_valid() && rt.is_valid() && is_uint5(msb) && is_uint5(lsb));
504 Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
505 | (msb << kRdShift) | (lsb << kSaShift) | func;
506 emit(instr);
507 }
508
509
510 void Assembler::GenInstrRegister(Opcode opcode,
470 SecondaryField fmt, 511 SecondaryField fmt,
471 FPURegister ft, 512 FPURegister ft,
472 FPURegister fs, 513 FPURegister fs,
473 FPURegister fd, 514 FPURegister fd,
474 SecondaryField func) { 515 SecondaryField func) {
475 ASSERT(fd.is_valid() && fs.is_valid() && ft.is_valid()); 516 ASSERT(fd.is_valid() && fs.is_valid() && ft.is_valid());
476 Instr instr = opcode | fmt | (ft.code() << 16) | (fs.code() << kFsShift) 517 Instr instr = opcode | fmt | (ft.code() << kFtShift) | (fs.code() << kFsShift)
477 | (fd.code() << 6) | func; 518 | (fd.code() << kFdShift) | func;
478 emit(instr); 519 emit(instr);
479 } 520 }
480 521
481 522
482 void Assembler::GenInstrRegister(Opcode opcode, 523 void Assembler::GenInstrRegister(Opcode opcode,
483 SecondaryField fmt, 524 SecondaryField fmt,
484 Register rt, 525 Register rt,
485 FPURegister fs, 526 FPURegister fs,
486 FPURegister fd, 527 FPURegister fd,
487 SecondaryField func) { 528 SecondaryField func) {
488 ASSERT(fd.is_valid() && fs.is_valid() && rt.is_valid()); 529 ASSERT(fd.is_valid() && fs.is_valid() && rt.is_valid());
489 Instr instr = opcode | fmt | (rt.code() << kRtShift) 530 Instr instr = opcode | fmt | (rt.code() << kRtShift)
490 | (fs.code() << kFsShift) | (fd.code() << 6) | func; 531 | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func;
491 emit(instr); 532 emit(instr);
492 } 533 }
493 534
494 535
495 // Instructions with immediate value. 536 // Instructions with immediate value.
496 // Registers are in the order of the instruction encoding, from left to right. 537 // Registers are in the order of the instruction encoding, from left to right.
497 void Assembler::GenInstrImmediate(Opcode opcode, 538 void Assembler::GenInstrImmediate(Opcode opcode,
498 Register rs, 539 Register rs,
499 Register rt, 540 Register rt,
500 int32_t j) { 541 int32_t j) {
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 681
641 void Assembler::jalr(Register rs, Register rd) { 682 void Assembler::jalr(Register rs, Register rd) {
642 GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR); 683 GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR);
643 } 684 }
644 685
645 686
646 //-------Data-processing-instructions--------- 687 //-------Data-processing-instructions---------
647 688
648 // Arithmetic. 689 // Arithmetic.
649 690
650 void Assembler::add(Register rd, Register rs, Register rt) {
651 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADD);
652 }
653
654
655 void Assembler::addu(Register rd, Register rs, Register rt) { 691 void Assembler::addu(Register rd, Register rs, Register rt) {
656 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU); 692 GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU);
657 } 693 }
658 694
659 695
660 void Assembler::addi(Register rd, Register rs, int32_t j) {
661 GenInstrImmediate(ADDI, rs, rd, j);
662 }
663
664
665 void Assembler::addiu(Register rd, Register rs, int32_t j) { 696 void Assembler::addiu(Register rd, Register rs, int32_t j) {
666 GenInstrImmediate(ADDIU, rs, rd, j); 697 GenInstrImmediate(ADDIU, rs, rd, j);
667 } 698 }
668 699
669 700
670 void Assembler::sub(Register rd, Register rs, Register rt) {
671 GenInstrRegister(SPECIAL, rs, rt, rd, 0, SUB);
672 }
673
674
675 void Assembler::subu(Register rd, Register rs, Register rt) { 701 void Assembler::subu(Register rd, Register rs, Register rt) {
676 GenInstrRegister(SPECIAL, rs, rt, rd, 0, SUBU); 702 GenInstrRegister(SPECIAL, rs, rt, rd, 0, SUBU);
677 } 703 }
678 704
679 705
680 void Assembler::mul(Register rd, Register rs, Register rt) { 706 void Assembler::mul(Register rd, Register rs, Register rt) {
681 GenInstrRegister(SPECIAL2, rs, rt, rd, 0, MUL); 707 GenInstrRegister(SPECIAL2, rs, rt, rd, 0, MUL);
682 } 708 }
683 709
684 710
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 void Assembler::lb(Register rd, const MemOperand& rs) { 801 void Assembler::lb(Register rd, const MemOperand& rs) {
776 GenInstrImmediate(LB, rs.rm(), rd, rs.offset_); 802 GenInstrImmediate(LB, rs.rm(), rd, rs.offset_);
777 } 803 }
778 804
779 805
780 void Assembler::lbu(Register rd, const MemOperand& rs) { 806 void Assembler::lbu(Register rd, const MemOperand& rs) {
781 GenInstrImmediate(LBU, rs.rm(), rd, rs.offset_); 807 GenInstrImmediate(LBU, rs.rm(), rd, rs.offset_);
782 } 808 }
783 809
784 810
811 void Assembler::lh(Register rd, const MemOperand& rs) {
812 GenInstrImmediate(LH, rs.rm(), rd, rs.offset_);
813 }
814
815
816 void Assembler::lhu(Register rd, const MemOperand& rs) {
817 GenInstrImmediate(LHU, rs.rm(), rd, rs.offset_);
818 }
819
820
785 void Assembler::lw(Register rd, const MemOperand& rs) { 821 void Assembler::lw(Register rd, const MemOperand& rs) {
786 GenInstrImmediate(LW, rs.rm(), rd, rs.offset_); 822 GenInstrImmediate(LW, rs.rm(), rd, rs.offset_);
787 } 823 }
788 824
789 825
790 void Assembler::sb(Register rd, const MemOperand& rs) { 826 void Assembler::sb(Register rd, const MemOperand& rs) {
791 GenInstrImmediate(SB, rs.rm(), rd, rs.offset_); 827 GenInstrImmediate(SB, rs.rm(), rd, rs.offset_);
792 } 828 }
793 829
794 830
831 void Assembler::sh(Register rd, const MemOperand& rs) {
832 GenInstrImmediate(SH, rs.rm(), rd, rs.offset_);
833 }
834
835
795 void Assembler::sw(Register rd, const MemOperand& rs) { 836 void Assembler::sw(Register rd, const MemOperand& rs) {
796 GenInstrImmediate(SW, rs.rm(), rd, rs.offset_); 837 GenInstrImmediate(SW, rs.rm(), rd, rs.offset_);
797 } 838 }
798 839
799 840
800 void Assembler::lui(Register rd, int32_t j) { 841 void Assembler::lui(Register rd, int32_t j) {
801 GenInstrImmediate(LUI, zero_reg, rd, j); 842 GenInstrImmediate(LUI, zero_reg, rd, j);
802 } 843 }
803 844
804 845
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 926
886 void Assembler::slti(Register rt, Register rs, int32_t j) { 927 void Assembler::slti(Register rt, Register rs, int32_t j) {
887 GenInstrImmediate(SLTI, rs, rt, j); 928 GenInstrImmediate(SLTI, rs, rt, j);
888 } 929 }
889 930
890 931
891 void Assembler::sltiu(Register rt, Register rs, int32_t j) { 932 void Assembler::sltiu(Register rt, Register rs, int32_t j) {
892 GenInstrImmediate(SLTIU, rs, rt, j); 933 GenInstrImmediate(SLTIU, rs, rt, j);
893 } 934 }
894 935
936 // Conditional move.
937 void Assembler::movz(Register rd, Register rs, Register rt) {
938 GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVZ);
939 }
940
941
942 void Assembler::movn(Register rd, Register rs, Register rt) {
943 GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVN);
944 }
945
946 // Bit twiddling.
947 void Assembler::clz(Register rd, Register rs) {
948 // Clz instr requires same GPR number in 'rd' and 'rt' fields.
949 GenInstrRegister(SPECIAL2, rs, rd, rd, 0, CLZ);
950 }
951
952
953 void Assembler::ins(Register rt, Register rs, uint16_t pos, uint16_t size) {
954 // Ins instr has 'rt' field as dest, and two uint5: msb, lsb
955 GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, INS);
956 }
957
958
959 void Assembler::ext(Register rt, Register rs, uint16_t pos, uint16_t size) {
960 // Ext instr has 'rt' field as dest, and two uint5: msb, lsb
961 GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, EXT);
962 }
963
895 964
896 //--------Coprocessor-instructions---------------- 965 //--------Coprocessor-instructions----------------
897 966
898 // Load, store, move. 967 // Load, store, move.
899 void Assembler::lwc1(FPURegister fd, const MemOperand& src) { 968 void Assembler::lwc1(FPURegister fd, const MemOperand& src) {
900 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_); 969 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_);
901 } 970 }
902 971
903 972
904 void Assembler::ldc1(FPURegister fd, const MemOperand& src) { 973 void Assembler::ldc1(FPURegister fd, const MemOperand& src) {
905 GenInstrImmediate(LDC1, src.rm(), fd, src.offset_); 974 // Workaround for non-8-byte alignment of HeapNumber, convert 64-bit
975 // load to two 32-bit loads. This really should be done in macro-assembler,
Søren Thygesen Gjesse 2010/05/25 09:00:56 I think you should just remove "This really should
976 // but this should be temporary....
977 GenInstrImmediate(LWC1, src.rm(), fd, src.offset_);
978 FPURegister nextfpreg;
979 nextfpreg.setcode(fd.code() + 1);
980 GenInstrImmediate(LWC1, src.rm(), nextfpreg, src.offset_ + 4);
981 // GenInstrImmediate(LDC1, src.rm(), fd, src.offset_);
Søren Thygesen Gjesse 2010/05/25 09:00:56 Please remove code in comments.
906 } 982 }
907 983
908 984
909 void Assembler::swc1(FPURegister fd, const MemOperand& src) { 985 void Assembler::swc1(FPURegister fd, const MemOperand& src) {
910 GenInstrImmediate(SWC1, src.rm(), fd, src.offset_); 986 GenInstrImmediate(SWC1, src.rm(), fd, src.offset_);
911 } 987 }
912 988
913 989
914 void Assembler::sdc1(FPURegister fd, const MemOperand& src) { 990 void Assembler::sdc1(FPURegister fd, const MemOperand& src) {
915 GenInstrImmediate(SDC1, src.rm(), fd, src.offset_); 991 // Workaround for non-8-byte alignment of HeapNumber, convert 64-bit
992 // store to two 32-bit stores. This really should be done in macro-assembler,
Søren Thygesen Gjesse 2010/05/25 09:00:56 Ditto.
993 // but this should be temporary....
994 GenInstrImmediate(SWC1, src.rm(), fd, src.offset_);
995 FPURegister nextfpreg;
996 nextfpreg.setcode(fd.code() + 1);
997 GenInstrImmediate(SWC1, src.rm(), nextfpreg, src.offset_ + 4);
998 // GenInstrImmediate(SDC1, src.rm(), fd, src.offset_);
Søren Thygesen Gjesse 2010/05/25 09:00:56 Ditto.
916 } 999 }
917 1000
918 1001
919 void Assembler::mtc1(FPURegister fs, Register rt) { 1002 void Assembler::mtc1(Register rt, FPURegister fs) {
920 GenInstrRegister(COP1, MTC1, rt, fs, f0); 1003 GenInstrRegister(COP1, MTC1, rt, fs, f0);
921 } 1004 }
922 1005
923 1006
924 void Assembler::mthc1(FPURegister fs, Register rt) { 1007 void Assembler::mfc1(Register rt, FPURegister fs) {
925 GenInstrRegister(COP1, MTHC1, rt, fs, f0);
926 }
927
928
929 void Assembler::mfc1(FPURegister fs, Register rt) {
930 GenInstrRegister(COP1, MFC1, rt, fs, f0); 1008 GenInstrRegister(COP1, MFC1, rt, fs, f0);
931 } 1009 }
932 1010
933 1011
934 void Assembler::mfhc1(FPURegister fs, Register rt) { 1012 // Arithmetic.
935 GenInstrRegister(COP1, MFHC1, rt, fs, f0); 1013
1014 void Assembler::add_d(FPURegister fd, FPURegister fs, FPURegister ft) {
1015 GenInstrRegister(COP1, D, ft, fs, fd, ADD_D);
1016 }
1017
1018 void Assembler::sub_d(FPURegister fd, FPURegister fs, FPURegister ft) {
1019 GenInstrRegister(COP1, D, ft, fs, fd, SUB_D);
1020 }
1021
1022 void Assembler::mul_d(FPURegister fd, FPURegister fs, FPURegister ft) {
1023 GenInstrRegister(COP1, D, ft, fs, fd, MUL_D);
1024 }
1025
1026 void Assembler::div_d(FPURegister fd, FPURegister fs, FPURegister ft) {
1027 GenInstrRegister(COP1, D, ft, fs, fd, DIV_D);
1028 }
1029
1030 void Assembler::abs_d(FPURegister fd, FPURegister fs) {
1031 GenInstrRegister(COP1, D, f0, fs, fd, ABS_D);
1032 }
1033
1034 void Assembler::mov_d(FPURegister fd, FPURegister fs) {
1035 GenInstrRegister(COP1, D, f0, fs, fd, MOV_D);
1036 }
1037
1038 void Assembler::neg_d(FPURegister fd, FPURegister fs) {
1039 GenInstrRegister(COP1, D, f0, fs, fd, NEG_D);
936 } 1040 }
937 1041
938 1042
939 // Conversions. 1043 // Conversions.
940 1044
941 void Assembler::cvt_w_s(FPURegister fd, FPURegister fs) { 1045 void Assembler::cvt_w_s(FPURegister fd, FPURegister fs) {
942 GenInstrRegister(COP1, S, f0, fs, fd, CVT_W_S); 1046 GenInstrRegister(COP1, S, f0, fs, fd, CVT_W_S);
943 } 1047 }
944 1048
945 1049
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
983 } 1087 }
984 1088
985 1089
986 void Assembler::cvt_d_s(FPURegister fd, FPURegister fs) { 1090 void Assembler::cvt_d_s(FPURegister fd, FPURegister fs) {
987 GenInstrRegister(COP1, S, f0, fs, fd, CVT_D_S); 1091 GenInstrRegister(COP1, S, f0, fs, fd, CVT_D_S);
988 } 1092 }
989 1093
990 1094
991 // Conditions. 1095 // Conditions.
992 void Assembler::c(FPUCondition cond, SecondaryField fmt, 1096 void Assembler::c(FPUCondition cond, SecondaryField fmt,
993 FPURegister ft, FPURegister fs, uint16_t cc) { 1097 FPURegister fs, FPURegister ft, uint16_t cc) {
994 ASSERT(is_uint3(cc)); 1098 ASSERT(is_uint3(cc));
995 ASSERT((fmt & ~(31 << kRsShift)) == 0); 1099 ASSERT((fmt & ~(31 << kRsShift)) == 0);
996 Instr instr = COP1 | fmt | ft.code() << 16 | fs.code() << kFsShift 1100 Instr instr = COP1 | fmt | ft.code() << 16 | fs.code() << kFsShift
997 | cc << 8 | 3 << 4 | cond; 1101 | cc << 8 | 3 << 4 | cond;
998 emit(instr); 1102 emit(instr);
999 } 1103 }
1000 1104
1001 1105
1002 void Assembler::bc1f(int16_t offset, uint16_t cc) { 1106 void Assembler::bc1f(int16_t offset, uint16_t cc) {
1003 ASSERT(is_uint3(cc)); 1107 ASSERT(is_uint3(cc));
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1199 *p = LUI | rt_code | ((itarget & HIMask)>>16); 1303 *p = LUI | rt_code | ((itarget & HIMask)>>16);
1200 *(p+1) = ORI | rt_code | (rt_code << 5) | (itarget & LOMask); 1304 *(p+1) = ORI | rt_code | (rt_code << 5) | (itarget & LOMask);
1201 } 1305 }
1202 1306
1203 CPU::FlushICache(pc, 2 * sizeof(int32_t)); 1307 CPU::FlushICache(pc, 2 * sizeof(int32_t));
1204 } 1308 }
1205 1309
1206 1310
1207 } } // namespace v8::internal 1311 } } // namespace v8::internal
1208 1312
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698