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 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 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 rd == static_cast<uint32_t>(ToNumber(zero_reg)) && | 576 rd == static_cast<uint32_t>(ToNumber(zero_reg)) && |
577 rt == static_cast<uint32_t>(ToNumber(nop_rt_reg)) && | 577 rt == static_cast<uint32_t>(ToNumber(nop_rt_reg)) && |
578 sa == type); | 578 sa == type); |
579 | 579 |
580 return ret; | 580 return ret; |
581 } | 581 } |
582 | 582 |
583 | 583 |
584 int32_t Assembler::GetBranchOffset(Instr instr) { | 584 int32_t Assembler::GetBranchOffset(Instr instr) { |
585 ASSERT(IsBranch(instr)); | 585 ASSERT(IsBranch(instr)); |
586 return ((int16_t)(instr & kImm16Mask)) << 2; | 586 return (static_cast<int16_t>(instr & kImm16Mask)) << 2; |
587 } | 587 } |
588 | 588 |
589 | 589 |
590 bool Assembler::IsLw(Instr instr) { | 590 bool Assembler::IsLw(Instr instr) { |
591 return ((instr & kOpcodeMask) == LW); | 591 return ((instr & kOpcodeMask) == LW); |
592 } | 592 } |
593 | 593 |
594 | 594 |
595 int16_t Assembler::GetLwOffset(Instr instr) { | 595 int16_t Assembler::GetLwOffset(Instr instr) { |
596 ASSERT(IsLw(instr)); | 596 ASSERT(IsLw(instr)); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 | 709 |
710 instr &= ~kImm16Mask; | 710 instr &= ~kImm16Mask; |
711 int32_t imm16 = imm18 >> 2; | 711 int32_t imm16 = imm18 >> 2; |
712 ASSERT(is_int16(imm16)); | 712 ASSERT(is_int16(imm16)); |
713 | 713 |
714 instr_at_put(pos, instr | (imm16 & kImm16Mask)); | 714 instr_at_put(pos, instr | (imm16 & kImm16Mask)); |
715 } else if (IsLui(instr)) { | 715 } else if (IsLui(instr)) { |
716 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); | 716 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); |
717 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); | 717 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); |
718 ASSERT(IsOri(instr_ori)); | 718 ASSERT(IsOri(instr_ori)); |
719 uint32_t imm = (uint32_t)buffer_ + target_pos; | 719 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; |
720 ASSERT((imm & 3) == 0); | 720 ASSERT((imm & 3) == 0); |
721 | 721 |
722 instr_lui &= ~kImm16Mask; | 722 instr_lui &= ~kImm16Mask; |
723 instr_ori &= ~kImm16Mask; | 723 instr_ori &= ~kImm16Mask; |
724 | 724 |
725 instr_at_put(pos + 0 * Assembler::kInstrSize, | 725 instr_at_put(pos + 0 * Assembler::kInstrSize, |
726 instr_lui | ((imm & kHiMask) >> kLuiShift)); | 726 instr_lui | ((imm & kHiMask) >> kLuiShift)); |
727 instr_at_put(pos + 1 * Assembler::kInstrSize, | 727 instr_at_put(pos + 1 * Assembler::kInstrSize, |
728 instr_ori | (imm & kImm16Mask)); | 728 instr_ori | (imm & kImm16Mask)); |
729 } else { | 729 } else { |
730 uint32_t imm28 = (uint32_t)buffer_ + target_pos; | 730 uint32_t imm28 = reinterpret_cast<uint32_t>(buffer_) + target_pos; |
731 imm28 &= kImm28Mask; | 731 imm28 &= kImm28Mask; |
732 ASSERT((imm28 & 3) == 0); | 732 ASSERT((imm28 & 3) == 0); |
733 | 733 |
734 instr &= ~kImm26Mask; | 734 instr &= ~kImm26Mask; |
735 uint32_t imm26 = imm28 >> 2; | 735 uint32_t imm26 = imm28 >> 2; |
736 ASSERT(is_uint26(imm26)); | 736 ASSERT(is_uint26(imm26)); |
737 | 737 |
738 instr_at_put(pos, instr | (imm26 & kImm26Mask)); | 738 instr_at_put(pos, instr | (imm26 & kImm26Mask)); |
739 } | 739 } |
740 } | 740 } |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 } else { | 972 } else { |
973 if (L->is_linked()) { | 973 if (L->is_linked()) { |
974 target_pos = L->pos(); // L's link. | 974 target_pos = L->pos(); // L's link. |
975 L->link_to(pc_offset()); | 975 L->link_to(pc_offset()); |
976 } else { | 976 } else { |
977 L->link_to(pc_offset()); | 977 L->link_to(pc_offset()); |
978 return kEndOfJumpChain; | 978 return kEndOfJumpChain; |
979 } | 979 } |
980 } | 980 } |
981 | 981 |
982 uint32_t imm = (uint32_t)buffer_ + target_pos; | 982 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; |
983 ASSERT((imm & 3) == 0); | 983 ASSERT((imm & 3) == 0); |
984 | 984 |
985 return imm; | 985 return imm; |
986 } | 986 } |
987 | 987 |
988 | 988 |
989 int32_t Assembler::branch_offset(Label* L, bool jump_elimination_allowed) { | 989 int32_t Assembler::branch_offset(Label* L, bool jump_elimination_allowed) { |
990 int32_t target_pos; | 990 int32_t target_pos; |
991 | 991 |
992 if (L->is_bound()) { | 992 if (L->is_bound()) { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1107 BlockTrampolinePoolScope block_trampoline_pool(this); | 1107 BlockTrampolinePoolScope block_trampoline_pool(this); |
1108 GenInstrImmediate(BNE, rs, rt, offset); | 1108 GenInstrImmediate(BNE, rs, rt, offset); |
1109 BlockTrampolinePoolFor(1); // For associated delay slot. | 1109 BlockTrampolinePoolFor(1); // For associated delay slot. |
1110 } | 1110 } |
1111 | 1111 |
1112 | 1112 |
1113 void Assembler::j(int32_t target) { | 1113 void Assembler::j(int32_t target) { |
1114 #if DEBUG | 1114 #if DEBUG |
1115 // Get pc of delay slot. | 1115 // Get pc of delay slot. |
1116 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); | 1116 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); |
1117 bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0; | 1117 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> |
| 1118 (kImm26Bits + kImmFieldShift)) == 0; |
1118 ASSERT(in_range && ((target & 3) == 0)); | 1119 ASSERT(in_range && ((target & 3) == 0)); |
1119 #endif | 1120 #endif |
1120 GenInstrJump(J, target >> 2); | 1121 GenInstrJump(J, target >> 2); |
1121 } | 1122 } |
1122 | 1123 |
1123 | 1124 |
1124 void Assembler::jr(Register rs) { | 1125 void Assembler::jr(Register rs) { |
1125 BlockTrampolinePoolScope block_trampoline_pool(this); | 1126 BlockTrampolinePoolScope block_trampoline_pool(this); |
1126 if (rs.is(ra)) { | 1127 if (rs.is(ra)) { |
1127 positions_recorder()->WriteRecordedPositions(); | 1128 positions_recorder()->WriteRecordedPositions(); |
1128 } | 1129 } |
1129 GenInstrRegister(SPECIAL, rs, zero_reg, zero_reg, 0, JR); | 1130 GenInstrRegister(SPECIAL, rs, zero_reg, zero_reg, 0, JR); |
1130 BlockTrampolinePoolFor(1); // For associated delay slot. | 1131 BlockTrampolinePoolFor(1); // For associated delay slot. |
1131 } | 1132 } |
1132 | 1133 |
1133 | 1134 |
1134 void Assembler::jal(int32_t target) { | 1135 void Assembler::jal(int32_t target) { |
1135 #ifdef DEBUG | 1136 #ifdef DEBUG |
1136 // Get pc of delay slot. | 1137 // Get pc of delay slot. |
1137 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); | 1138 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); |
1138 bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0; | 1139 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> |
| 1140 (kImm26Bits + kImmFieldShift)) == 0; |
1139 ASSERT(in_range && ((target & 3) == 0)); | 1141 ASSERT(in_range && ((target & 3) == 0)); |
1140 #endif | 1142 #endif |
1141 positions_recorder()->WriteRecordedPositions(); | 1143 positions_recorder()->WriteRecordedPositions(); |
1142 GenInstrJump(JAL, target >> 2); | 1144 GenInstrJump(JAL, target >> 2); |
1143 } | 1145 } |
1144 | 1146 |
1145 | 1147 |
1146 void Assembler::jalr(Register rs, Register rd) { | 1148 void Assembler::jalr(Register rs, Register rd) { |
1147 BlockTrampolinePoolScope block_trampoline_pool(this); | 1149 BlockTrampolinePoolScope block_trampoline_pool(this); |
1148 positions_recorder()->WriteRecordedPositions(); | 1150 positions_recorder()->WriteRecordedPositions(); |
1149 GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR); | 1151 GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR); |
1150 BlockTrampolinePoolFor(1); // For associated delay slot. | 1152 BlockTrampolinePoolFor(1); // For associated delay slot. |
1151 } | 1153 } |
1152 | 1154 |
1153 | 1155 |
1154 void Assembler::j_or_jr(int32_t target, Register rs) { | 1156 void Assembler::j_or_jr(int32_t target, Register rs) { |
1155 // Get pc of delay slot. | 1157 // Get pc of delay slot. |
1156 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); | 1158 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); |
1157 bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0; | 1159 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> |
1158 | 1160 (kImm26Bits + kImmFieldShift)) == 0; |
1159 if (in_range) { | 1161 if (in_range) { |
1160 j(target); | 1162 j(target); |
1161 } else { | 1163 } else { |
1162 jr(t9); | 1164 jr(t9); |
1163 } | 1165 } |
1164 } | 1166 } |
1165 | 1167 |
1166 | 1168 |
1167 void Assembler::jal_or_jalr(int32_t target, Register rs) { | 1169 void Assembler::jal_or_jalr(int32_t target, Register rs) { |
1168 // Get pc of delay slot. | 1170 // Get pc of delay slot. |
1169 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); | 1171 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); |
1170 bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0; | 1172 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> |
1171 | 1173 (kImm26Bits+kImmFieldShift)) == 0; |
1172 if (in_range) { | 1174 if (in_range) { |
1173 jal(target); | 1175 jal(target); |
1174 } else { | 1176 } else { |
1175 jalr(t9); | 1177 jalr(t9); |
1176 } | 1178 } |
1177 } | 1179 } |
1178 | 1180 |
1179 | 1181 |
1180 //-------Data-processing-instructions--------- | 1182 //-------Data-processing-instructions--------- |
1181 | 1183 |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1920 instr_lui &= ~kImm16Mask; | 1922 instr_lui &= ~kImm16Mask; |
1921 instr_ori &= ~kImm16Mask; | 1923 instr_ori &= ~kImm16Mask; |
1922 | 1924 |
1923 instr_at_put(pc + 0 * Assembler::kInstrSize, | 1925 instr_at_put(pc + 0 * Assembler::kInstrSize, |
1924 instr_lui | ((imm >> kLuiShift) & kImm16Mask)); | 1926 instr_lui | ((imm >> kLuiShift) & kImm16Mask)); |
1925 instr_at_put(pc + 1 * Assembler::kInstrSize, | 1927 instr_at_put(pc + 1 * Assembler::kInstrSize, |
1926 instr_ori | (imm & kImm16Mask)); | 1928 instr_ori | (imm & kImm16Mask)); |
1927 return 2; // Number of instructions patched. | 1929 return 2; // Number of instructions patched. |
1928 } else { | 1930 } else { |
1929 uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; | 1931 uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; |
1930 if ((int32_t)imm28 == kEndOfJumpChain) { | 1932 if (static_cast<int32_t>(imm28) == kEndOfJumpChain) { |
1931 return 0; // Number of instructions patched. | 1933 return 0; // Number of instructions patched. |
1932 } | 1934 } |
1933 imm28 += pc_delta; | 1935 imm28 += pc_delta; |
1934 imm28 &= kImm28Mask; | 1936 imm28 &= kImm28Mask; |
1935 ASSERT((imm28 & 3) == 0); | 1937 ASSERT((imm28 & 3) == 0); |
1936 | 1938 |
1937 instr &= ~kImm26Mask; | 1939 instr &= ~kImm26Mask; |
1938 uint32_t imm26 = imm28 >> 2; | 1940 uint32_t imm26 = imm28 >> 2; |
1939 ASSERT(is_uint26(imm26)); | 1941 ASSERT(is_uint26(imm26)); |
1940 | 1942 |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2170 // 256 MB page. Note that with the jal/j instructions, we do not need to | 2172 // 256 MB page. Note that with the jal/j instructions, we do not need to |
2171 // load the register, but that code is left, since it makes it easy to | 2173 // load the register, but that code is left, since it makes it easy to |
2172 // revert this process. A further optimization could try replacing the | 2174 // revert this process. A further optimization could try replacing the |
2173 // li sequence with nops. | 2175 // li sequence with nops. |
2174 // This optimization can only be applied if the rt-code from instr2 is the | 2176 // This optimization can only be applied if the rt-code from instr2 is the |
2175 // register used for the jalr/jr. Finally, we have to skip 'jr ra', which is | 2177 // register used for the jalr/jr. Finally, we have to skip 'jr ra', which is |
2176 // mips return. Occasionally this lands after an li(). | 2178 // mips return. Occasionally this lands after an li(). |
2177 | 2179 |
2178 Instr instr3 = instr_at(pc + 2 * kInstrSize); | 2180 Instr instr3 = instr_at(pc + 2 * kInstrSize); |
2179 uint32_t ipc = reinterpret_cast<uint32_t>(pc + 3 * kInstrSize); | 2181 uint32_t ipc = reinterpret_cast<uint32_t>(pc + 3 * kInstrSize); |
2180 bool in_range = | 2182 bool in_range = (ipc ^ static_cast<uint32_t>(itarget) >> |
2181 ((uint32_t)(ipc ^ itarget) >> (kImm26Bits + kImmFieldShift)) == 0; | 2183 (kImm26Bits + kImmFieldShift)) == 0; |
2182 uint32_t target_field = (uint32_t)(itarget & kJumpAddrMask) >> kImmFieldShift; | 2184 uint32_t target_field = |
| 2185 static_cast<uint32_t>(itarget & kJumpAddrMask) >>kImmFieldShift; |
2183 bool patched_jump = false; | 2186 bool patched_jump = false; |
2184 | 2187 |
2185 #ifndef ALLOW_JAL_IN_BOUNDARY_REGION | 2188 #ifndef ALLOW_JAL_IN_BOUNDARY_REGION |
2186 // This is a workaround to the 24k core E156 bug (affect some 34k cores also). | 2189 // This is a workaround to the 24k core E156 bug (affect some 34k cores also). |
2187 // Since the excluded space is only 64KB out of 256MB (0.02 %), we will just | 2190 // Since the excluded space is only 64KB out of 256MB (0.02 %), we will just |
2188 // apply this workaround for all cores so we don't have to identify the core. | 2191 // apply this workaround for all cores so we don't have to identify the core. |
2189 if (in_range) { | 2192 if (in_range) { |
2190 // The 24k core E156 bug has some very specific requirements, we only check | 2193 // The 24k core E156 bug has some very specific requirements, we only check |
2191 // the most simple one: if the address of the delay slot instruction is in | 2194 // the most simple one: if the address of the delay slot instruction is in |
2192 // the first or last 32 KB of the 256 MB segment. | 2195 // the first or last 32 KB of the 256 MB segment. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2267 } | 2270 } |
2268 | 2271 |
2269 if (patched) { | 2272 if (patched) { |
2270 CPU::FlushICache(pc+2, sizeof(Address)); | 2273 CPU::FlushICache(pc+2, sizeof(Address)); |
2271 } | 2274 } |
2272 } | 2275 } |
2273 | 2276 |
2274 } } // namespace v8::internal | 2277 } } // namespace v8::internal |
2275 | 2278 |
2276 #endif // V8_TARGET_ARCH_MIPS | 2279 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |