| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_ASSEMBLER_MIPS_H_ | 5 #ifndef VM_ASSEMBLER_MIPS_H_ |
| 6 #define VM_ASSEMBLER_MIPS_H_ | 6 #define VM_ASSEMBLER_MIPS_H_ |
| 7 | 7 |
| 8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
| 9 #error Do not include assembler_mips.h directly; use assembler.h instead. | 9 #error Do not include assembler_mips.h directly; use assembler.h instead. |
| 10 #endif | 10 #endif |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 | 43 |
| 44 friend class Assembler; | 44 friend class Assembler; |
| 45 }; | 45 }; |
| 46 | 46 |
| 47 | 47 |
| 48 class Address : public ValueObject { | 48 class Address : public ValueObject { |
| 49 public: | 49 public: |
| 50 explicit Address(Register base, int32_t offset = 0) | 50 explicit Address(Register base, int32_t offset = 0) |
| 51 : ValueObject(), base_(base), offset_(offset) { } | 51 : ValueObject(), base_(base), offset_(offset) { } |
| 52 | 52 |
| 53 // This addressing mode does not exist. |
| 54 Address(Register base, Register offset); |
| 55 |
| 53 Address(const Address& other) | 56 Address(const Address& other) |
| 54 : ValueObject(), base_(other.base_), offset_(other.offset_) { } | 57 : ValueObject(), base_(other.base_), offset_(other.offset_) { } |
| 55 Address& operator=(const Address& other) { | 58 Address& operator=(const Address& other) { |
| 56 base_ = other.base_; | 59 base_ = other.base_; |
| 57 offset_ = other.offset_; | 60 offset_ = other.offset_; |
| 58 return *this; | 61 return *this; |
| 59 } | 62 } |
| 60 | 63 |
| 61 uint32_t encoding() const { | 64 uint32_t encoding() const { |
| 62 ASSERT(Utils::IsInt(kImmBits, offset_)); | 65 ASSERT(Utils::IsInt(kImmBits, offset_)); |
| (...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 } else { | 928 } else { |
| 926 LoadImmediate(TMP, imm); | 929 LoadImmediate(TMP, imm); |
| 927 and_(rd, rs, TMP); | 930 and_(rd, rs, TMP); |
| 928 } | 931 } |
| 929 } | 932 } |
| 930 | 933 |
| 931 void BranchEqual(Register rd, Register rn, Label* l) { | 934 void BranchEqual(Register rd, Register rn, Label* l) { |
| 932 beq(rd, rn, l); | 935 beq(rd, rn, l); |
| 933 } | 936 } |
| 934 | 937 |
| 935 void BranchEqual(Register rd, int32_t value, Label* l) { | 938 void BranchEqual(Register rd, const Immediate& imm, Label* l) { |
| 936 ASSERT(!in_delay_slot_); | 939 ASSERT(!in_delay_slot_); |
| 937 if (value == 0) { | 940 if (imm.value() == 0) { |
| 938 beq(rd, ZR, l); | 941 beq(rd, ZR, l); |
| 939 } else { | 942 } else { |
| 940 ASSERT(rd != CMPRES2); | 943 ASSERT(rd != CMPRES2); |
| 941 LoadImmediate(CMPRES2, value); | 944 LoadImmediate(CMPRES2, imm.value()); |
| 942 beq(rd, CMPRES2, l); | 945 beq(rd, CMPRES2, l); |
| 943 } | 946 } |
| 944 } | 947 } |
| 945 | 948 |
| 946 void BranchEqual(Register rd, const Object& object, Label* l) { | 949 void BranchEqual(Register rd, const Object& object, Label* l) { |
| 947 ASSERT(!in_delay_slot_); | 950 ASSERT(!in_delay_slot_); |
| 948 ASSERT(rd != CMPRES2); | 951 ASSERT(rd != CMPRES2); |
| 949 LoadObject(CMPRES2, object); | 952 LoadObject(CMPRES2, object); |
| 950 beq(rd, CMPRES2, l); | 953 beq(rd, CMPRES2, l); |
| 951 } | 954 } |
| 952 | 955 |
| 953 void BranchNotEqual(Register rd, Register rn, Label* l) { | 956 void BranchNotEqual(Register rd, Register rn, Label* l) { |
| 954 bne(rd, rn, l); | 957 bne(rd, rn, l); |
| 955 } | 958 } |
| 956 | 959 |
| 957 void BranchNotEqual(Register rd, int32_t value, Label* l) { | 960 void BranchNotEqual(Register rd, const Immediate& imm, Label* l) { |
| 958 ASSERT(!in_delay_slot_); | 961 ASSERT(!in_delay_slot_); |
| 959 if (value == 0) { | 962 if (imm.value() == 0) { |
| 960 bne(rd, ZR, l); | 963 bne(rd, ZR, l); |
| 961 } else { | 964 } else { |
| 962 ASSERT(rd != CMPRES2); | 965 ASSERT(rd != CMPRES2); |
| 963 LoadImmediate(CMPRES2, value); | 966 LoadImmediate(CMPRES2, imm.value()); |
| 964 bne(rd, CMPRES2, l); | 967 bne(rd, CMPRES2, l); |
| 965 } | 968 } |
| 966 } | 969 } |
| 967 | 970 |
| 968 void BranchNotEqual(Register rd, const Object& object, Label* l) { | 971 void BranchNotEqual(Register rd, const Object& object, Label* l) { |
| 969 ASSERT(!in_delay_slot_); | 972 ASSERT(!in_delay_slot_); |
| 970 ASSERT(rd != CMPRES2); | 973 ASSERT(rd != CMPRES2); |
| 971 LoadObject(CMPRES2, object); | 974 LoadObject(CMPRES2, object); |
| 972 bne(rd, CMPRES2, l); | 975 bne(rd, CMPRES2, l); |
| 973 } | 976 } |
| 974 | 977 |
| 975 void BranchSignedGreater(Register rd, Register rs, Label* l) { | 978 void BranchSignedGreater(Register rd, Register rs, Label* l) { |
| 976 ASSERT(!in_delay_slot_); | 979 ASSERT(!in_delay_slot_); |
| 977 slt(CMPRES2, rs, rd); // CMPRES2 = rd > rs ? 1 : 0. | 980 slt(CMPRES2, rs, rd); // CMPRES2 = rd > rs ? 1 : 0. |
| 978 bne(CMPRES2, ZR, l); | 981 bne(CMPRES2, ZR, l); |
| 979 } | 982 } |
| 980 | 983 |
| 981 void BranchSignedGreater(Register rd, int32_t value, Label* l) { | 984 void BranchSignedGreater(Register rd, const Immediate& imm, Label* l) { |
| 982 ASSERT(!in_delay_slot_); | 985 ASSERT(!in_delay_slot_); |
| 983 if (value == 0) { | 986 if (imm.value() == 0) { |
| 984 bgtz(rd, l); | 987 bgtz(rd, l); |
| 985 } else { | 988 } else { |
| 986 ASSERT(rd != CMPRES2); | 989 ASSERT(rd != CMPRES2); |
| 987 LoadImmediate(CMPRES2, value); | 990 LoadImmediate(CMPRES2, imm.value()); |
| 988 BranchSignedGreater(rd, CMPRES2, l); | 991 BranchSignedGreater(rd, CMPRES2, l); |
| 989 } | 992 } |
| 990 } | 993 } |
| 991 | 994 |
| 992 void BranchUnsignedGreater(Register rd, Register rs, Label* l) { | 995 void BranchUnsignedGreater(Register rd, Register rs, Label* l) { |
| 993 ASSERT(!in_delay_slot_); | 996 ASSERT(!in_delay_slot_); |
| 994 sltu(CMPRES2, rs, rd); | 997 sltu(CMPRES2, rs, rd); |
| 995 bne(CMPRES2, ZR, l); | 998 bne(CMPRES2, ZR, l); |
| 996 } | 999 } |
| 997 | 1000 |
| 998 void BranchUnsignedGreater(Register rd, int32_t value, Label* l) { | 1001 void BranchUnsignedGreater(Register rd, const Immediate& imm, Label* l) { |
| 999 ASSERT(!in_delay_slot_); | 1002 ASSERT(!in_delay_slot_); |
| 1000 if (value == 0) { | 1003 if (imm.value() == 0) { |
| 1001 BranchNotEqual(rd, 0, l); | 1004 BranchNotEqual(rd, Immediate(0), l); |
| 1002 } else { | 1005 } else { |
| 1003 ASSERT(rd != CMPRES2); | 1006 ASSERT(rd != CMPRES2); |
| 1004 LoadImmediate(CMPRES2, value); | 1007 LoadImmediate(CMPRES2, imm.value()); |
| 1005 BranchUnsignedGreater(rd, CMPRES2, l); | 1008 BranchUnsignedGreater(rd, CMPRES2, l); |
| 1006 } | 1009 } |
| 1007 } | 1010 } |
| 1008 | 1011 |
| 1009 void BranchSignedGreaterEqual(Register rd, Register rs, Label* l) { | 1012 void BranchSignedGreaterEqual(Register rd, Register rs, Label* l) { |
| 1010 ASSERT(!in_delay_slot_); | 1013 ASSERT(!in_delay_slot_); |
| 1011 slt(CMPRES2, rd, rs); // CMPRES2 = rd < rs ? 1 : 0. | 1014 slt(CMPRES2, rd, rs); // CMPRES2 = rd < rs ? 1 : 0. |
| 1012 beq(CMPRES2, ZR, l); // If CMPRES2 = 0, then rd >= rs. | 1015 beq(CMPRES2, ZR, l); // If CMPRES2 = 0, then rd >= rs. |
| 1013 } | 1016 } |
| 1014 | 1017 |
| 1015 void BranchSignedGreaterEqual(Register rd, int32_t value, Label* l) { | 1018 void BranchSignedGreaterEqual(Register rd, const Immediate& imm, Label* l) { |
| 1016 ASSERT(!in_delay_slot_); | 1019 ASSERT(!in_delay_slot_); |
| 1017 if (value == 0) { | 1020 if (imm.value() == 0) { |
| 1018 bgez(rd, l); | 1021 bgez(rd, l); |
| 1019 } else { | 1022 } else { |
| 1020 if (Utils::IsInt(kImmBits, value)) { | 1023 if (Utils::IsInt(kImmBits, imm.value())) { |
| 1021 slti(CMPRES2, rd, Immediate(value)); | 1024 slti(CMPRES2, rd, imm); |
| 1022 beq(CMPRES2, ZR, l); | 1025 beq(CMPRES2, ZR, l); |
| 1023 } else { | 1026 } else { |
| 1024 ASSERT(rd != CMPRES2); | 1027 ASSERT(rd != CMPRES2); |
| 1025 LoadImmediate(CMPRES2, value); | 1028 LoadImmediate(CMPRES2, imm.value()); |
| 1026 BranchSignedGreaterEqual(rd, CMPRES2, l); | 1029 BranchSignedGreaterEqual(rd, CMPRES2, l); |
| 1027 } | 1030 } |
| 1028 } | 1031 } |
| 1029 } | 1032 } |
| 1030 | 1033 |
| 1031 void BranchUnsignedGreaterEqual(Register rd, Register rs, Label* l) { | 1034 void BranchUnsignedGreaterEqual(Register rd, Register rs, Label* l) { |
| 1032 ASSERT(!in_delay_slot_); | 1035 ASSERT(!in_delay_slot_); |
| 1033 sltu(CMPRES2, rd, rs); // CMPRES2 = rd < rs ? 1 : 0. | 1036 sltu(CMPRES2, rd, rs); // CMPRES2 = rd < rs ? 1 : 0. |
| 1034 beq(CMPRES2, ZR, l); | 1037 beq(CMPRES2, ZR, l); |
| 1035 } | 1038 } |
| 1036 | 1039 |
| 1037 void BranchUnsignedGreaterEqual(Register rd, int32_t value, Label* l) { | 1040 void BranchUnsignedGreaterEqual(Register rd, const Immediate& imm, Label* l) { |
| 1038 ASSERT(!in_delay_slot_); | 1041 ASSERT(!in_delay_slot_); |
| 1039 if (value == 0) { | 1042 if (imm.value() == 0) { |
| 1040 b(l); | 1043 b(l); |
| 1041 } else { | 1044 } else { |
| 1042 if (Utils::IsUint(kImmBits, value)) { | 1045 if (Utils::IsUint(kImmBits, imm.value())) { |
| 1043 sltiu(CMPRES2, rd, Immediate(value)); | 1046 sltiu(CMPRES2, rd, imm); |
| 1044 beq(CMPRES2, ZR, l); | 1047 beq(CMPRES2, ZR, l); |
| 1045 } else { | 1048 } else { |
| 1046 ASSERT(rd != CMPRES2); | 1049 ASSERT(rd != CMPRES2); |
| 1047 LoadImmediate(CMPRES2, value); | 1050 LoadImmediate(CMPRES2, imm.value()); |
| 1048 BranchUnsignedGreaterEqual(rd, CMPRES2, l); | 1051 BranchUnsignedGreaterEqual(rd, CMPRES2, l); |
| 1049 } | 1052 } |
| 1050 } | 1053 } |
| 1051 } | 1054 } |
| 1052 | 1055 |
| 1053 void BranchSignedLess(Register rd, Register rs, Label* l) { | 1056 void BranchSignedLess(Register rd, Register rs, Label* l) { |
| 1054 ASSERT(!in_delay_slot_); | 1057 ASSERT(!in_delay_slot_); |
| 1055 BranchSignedGreater(rs, rd, l); | 1058 BranchSignedGreater(rs, rd, l); |
| 1056 } | 1059 } |
| 1057 | 1060 |
| 1058 void BranchSignedLess(Register rd, int32_t value, Label* l) { | 1061 void BranchSignedLess(Register rd, const Immediate& imm, Label* l) { |
| 1059 ASSERT(!in_delay_slot_); | 1062 ASSERT(!in_delay_slot_); |
| 1060 if (value == 0) { | 1063 if (imm.value() == 0) { |
| 1061 bltz(rd, l); | 1064 bltz(rd, l); |
| 1062 } else { | 1065 } else { |
| 1063 if (Utils::IsInt(kImmBits, value)) { | 1066 if (Utils::IsInt(kImmBits, imm.value())) { |
| 1064 slti(CMPRES2, rd, Immediate(value)); | 1067 slti(CMPRES2, rd, imm); |
| 1065 bne(CMPRES2, ZR, l); | 1068 bne(CMPRES2, ZR, l); |
| 1066 } else { | 1069 } else { |
| 1067 ASSERT(rd != CMPRES2); | 1070 ASSERT(rd != CMPRES2); |
| 1068 LoadImmediate(CMPRES2, value); | 1071 LoadImmediate(CMPRES2, imm.value()); |
| 1069 BranchSignedGreater(CMPRES2, rd, l); | 1072 BranchSignedGreater(CMPRES2, rd, l); |
| 1070 } | 1073 } |
| 1071 } | 1074 } |
| 1072 } | 1075 } |
| 1073 | 1076 |
| 1074 void BranchUnsignedLess(Register rd, Register rs, Label* l) { | 1077 void BranchUnsignedLess(Register rd, Register rs, Label* l) { |
| 1075 ASSERT(!in_delay_slot_); | 1078 ASSERT(!in_delay_slot_); |
| 1076 BranchUnsignedGreater(rs, rd, l); | 1079 BranchUnsignedGreater(rs, rd, l); |
| 1077 } | 1080 } |
| 1078 | 1081 |
| 1079 void BranchUnsignedLess(Register rd, int32_t value, Label* l) { | 1082 void BranchUnsignedLess(Register rd, const Immediate& imm, Label* l) { |
| 1080 ASSERT(!in_delay_slot_); | 1083 ASSERT(!in_delay_slot_); |
| 1081 ASSERT(value != 0); | 1084 ASSERT(imm.value() != 0); |
| 1082 if (Utils::IsUint(kImmBits, value)) { | 1085 if (Utils::IsUint(kImmBits, imm.value())) { |
| 1083 sltiu(CMPRES2, rd, Immediate(value)); | 1086 sltiu(CMPRES2, rd, imm); |
| 1084 bne(CMPRES2, ZR, l); | 1087 bne(CMPRES2, ZR, l); |
| 1085 } else { | 1088 } else { |
| 1086 ASSERT(rd != CMPRES2); | 1089 ASSERT(rd != CMPRES2); |
| 1087 LoadImmediate(CMPRES2, value); | 1090 LoadImmediate(CMPRES2, imm.value()); |
| 1088 BranchUnsignedGreater(CMPRES2, rd, l); | 1091 BranchUnsignedGreater(CMPRES2, rd, l); |
| 1089 } | 1092 } |
| 1090 } | 1093 } |
| 1091 | 1094 |
| 1092 void BranchSignedLessEqual(Register rd, Register rs, Label* l) { | 1095 void BranchSignedLessEqual(Register rd, Register rs, Label* l) { |
| 1093 ASSERT(!in_delay_slot_); | 1096 ASSERT(!in_delay_slot_); |
| 1094 BranchSignedGreaterEqual(rs, rd, l); | 1097 BranchSignedGreaterEqual(rs, rd, l); |
| 1095 } | 1098 } |
| 1096 | 1099 |
| 1097 void BranchSignedLessEqual(Register rd, int32_t value, Label* l) { | 1100 void BranchSignedLessEqual(Register rd, const Immediate& imm, Label* l) { |
| 1098 ASSERT(!in_delay_slot_); | 1101 ASSERT(!in_delay_slot_); |
| 1099 if (value == 0) { | 1102 if (imm.value() == 0) { |
| 1100 blez(rd, l); | 1103 blez(rd, l); |
| 1101 } else { | 1104 } else { |
| 1102 ASSERT(rd != CMPRES2); | 1105 ASSERT(rd != CMPRES2); |
| 1103 LoadImmediate(CMPRES2, value); | 1106 LoadImmediate(CMPRES2, imm.value()); |
| 1104 BranchSignedGreaterEqual(CMPRES2, rd, l); | 1107 BranchSignedGreaterEqual(CMPRES2, rd, l); |
| 1105 } | 1108 } |
| 1106 } | 1109 } |
| 1107 | 1110 |
| 1108 void BranchUnsignedLessEqual(Register rd, Register rs, Label* l) { | 1111 void BranchUnsignedLessEqual(Register rd, Register rs, Label* l) { |
| 1109 ASSERT(!in_delay_slot_); | 1112 ASSERT(!in_delay_slot_); |
| 1110 BranchUnsignedGreaterEqual(rs, rd, l); | 1113 BranchUnsignedGreaterEqual(rs, rd, l); |
| 1111 } | 1114 } |
| 1112 | 1115 |
| 1113 void BranchUnsignedLessEqual(Register rd, int32_t value, Label* l) { | 1116 void BranchUnsignedLessEqual(Register rd, const Immediate& imm, Label* l) { |
| 1114 ASSERT(!in_delay_slot_); | 1117 ASSERT(!in_delay_slot_); |
| 1115 ASSERT(rd != CMPRES2); | 1118 ASSERT(rd != CMPRES2); |
| 1116 LoadImmediate(CMPRES2, value); | 1119 LoadImmediate(CMPRES2, imm.value()); |
| 1117 BranchUnsignedGreaterEqual(CMPRES2, rd, l); | 1120 BranchUnsignedGreaterEqual(CMPRES2, rd, l); |
| 1118 } | 1121 } |
| 1119 | 1122 |
| 1120 void Push(Register rt) { | 1123 void Push(Register rt) { |
| 1121 ASSERT(!in_delay_slot_); | 1124 ASSERT(!in_delay_slot_); |
| 1122 addiu(SP, SP, Immediate(-kWordSize)); | 1125 addiu(SP, SP, Immediate(-kWordSize)); |
| 1123 sw(rt, Address(SP)); | 1126 sw(rt, Address(SP)); |
| 1124 } | 1127 } |
| 1125 | 1128 |
| 1126 void Pop(Register rt) { | 1129 void Pop(Register rt) { |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1406 Register value, | 1409 Register value, |
| 1407 Label* no_update); | 1410 Label* no_update); |
| 1408 | 1411 |
| 1409 DISALLOW_ALLOCATION(); | 1412 DISALLOW_ALLOCATION(); |
| 1410 DISALLOW_COPY_AND_ASSIGN(Assembler); | 1413 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 1411 }; | 1414 }; |
| 1412 | 1415 |
| 1413 } // namespace dart | 1416 } // namespace dart |
| 1414 | 1417 |
| 1415 #endif // VM_ASSEMBLER_MIPS_H_ | 1418 #endif // VM_ASSEMBLER_MIPS_H_ |
| OLD | NEW |