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 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 rd == static_cast<uint32_t>(ToNumber(zero_reg)) && | 549 rd == static_cast<uint32_t>(ToNumber(zero_reg)) && |
550 rt == static_cast<uint32_t>(ToNumber(nop_rt_reg)) && | 550 rt == static_cast<uint32_t>(ToNumber(nop_rt_reg)) && |
551 sa == type); | 551 sa == type); |
552 | 552 |
553 return ret; | 553 return ret; |
554 } | 554 } |
555 | 555 |
556 | 556 |
557 int32_t Assembler::GetBranchOffset(Instr instr) { | 557 int32_t Assembler::GetBranchOffset(Instr instr) { |
558 ASSERT(IsBranch(instr)); | 558 ASSERT(IsBranch(instr)); |
559 return ((int16_t)(instr & kImm16Mask)) << 2; | 559 return (static_cast<int16_t>(instr & kImm16Mask)) << 2; |
560 } | 560 } |
561 | 561 |
562 | 562 |
563 bool Assembler::IsLw(Instr instr) { | 563 bool Assembler::IsLw(Instr instr) { |
564 return ((instr & kOpcodeMask) == LW); | 564 return ((instr & kOpcodeMask) == LW); |
565 } | 565 } |
566 | 566 |
567 | 567 |
568 int16_t Assembler::GetLwOffset(Instr instr) { | 568 int16_t Assembler::GetLwOffset(Instr instr) { |
569 ASSERT(IsLw(instr)); | 569 ASSERT(IsLw(instr)); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 | 682 |
683 instr &= ~kImm16Mask; | 683 instr &= ~kImm16Mask; |
684 int32_t imm16 = imm18 >> 2; | 684 int32_t imm16 = imm18 >> 2; |
685 ASSERT(is_int16(imm16)); | 685 ASSERT(is_int16(imm16)); |
686 | 686 |
687 instr_at_put(pos, instr | (imm16 & kImm16Mask)); | 687 instr_at_put(pos, instr | (imm16 & kImm16Mask)); |
688 } else if (IsLui(instr)) { | 688 } else if (IsLui(instr)) { |
689 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); | 689 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); |
690 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); | 690 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); |
691 ASSERT(IsOri(instr_ori)); | 691 ASSERT(IsOri(instr_ori)); |
692 uint32_t imm = (uint32_t)buffer_ + target_pos; | 692 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; |
693 ASSERT((imm & 3) == 0); | 693 ASSERT((imm & 3) == 0); |
694 | 694 |
695 instr_lui &= ~kImm16Mask; | 695 instr_lui &= ~kImm16Mask; |
696 instr_ori &= ~kImm16Mask; | 696 instr_ori &= ~kImm16Mask; |
697 | 697 |
698 instr_at_put(pos + 0 * Assembler::kInstrSize, | 698 instr_at_put(pos + 0 * Assembler::kInstrSize, |
699 instr_lui | ((imm & kHiMask) >> kLuiShift)); | 699 instr_lui | ((imm & kHiMask) >> kLuiShift)); |
700 instr_at_put(pos + 1 * Assembler::kInstrSize, | 700 instr_at_put(pos + 1 * Assembler::kInstrSize, |
701 instr_ori | (imm & kImm16Mask)); | 701 instr_ori | (imm & kImm16Mask)); |
702 } else { | 702 } else { |
703 uint32_t imm28 = (uint32_t)buffer_ + target_pos; | 703 uint32_t imm28 = reinterpret_cast<uint32_t>(buffer_) + target_pos; |
704 imm28 &= kImm28Mask; | 704 imm28 &= kImm28Mask; |
705 ASSERT((imm28 & 3) == 0); | 705 ASSERT((imm28 & 3) == 0); |
706 | 706 |
707 instr &= ~kImm26Mask; | 707 instr &= ~kImm26Mask; |
708 uint32_t imm26 = imm28 >> 2; | 708 uint32_t imm26 = imm28 >> 2; |
709 ASSERT(is_uint26(imm26)); | 709 ASSERT(is_uint26(imm26)); |
710 | 710 |
711 instr_at_put(pos, instr | (imm26 & kImm26Mask)); | 711 instr_at_put(pos, instr | (imm26 & kImm26Mask)); |
712 } | 712 } |
713 } | 713 } |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 } else { | 945 } else { |
946 if (L->is_linked()) { | 946 if (L->is_linked()) { |
947 target_pos = L->pos(); // L's link. | 947 target_pos = L->pos(); // L's link. |
948 L->link_to(pc_offset()); | 948 L->link_to(pc_offset()); |
949 } else { | 949 } else { |
950 L->link_to(pc_offset()); | 950 L->link_to(pc_offset()); |
951 return kEndOfJumpChain; | 951 return kEndOfJumpChain; |
952 } | 952 } |
953 } | 953 } |
954 | 954 |
955 uint32_t imm = (uint32_t)buffer_ + target_pos; | 955 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; |
956 ASSERT((imm & 3) == 0); | 956 ASSERT((imm & 3) == 0); |
957 | 957 |
958 return imm; | 958 return imm; |
959 } | 959 } |
960 | 960 |
961 | 961 |
962 int32_t Assembler::branch_offset(Label* L, bool jump_elimination_allowed) { | 962 int32_t Assembler::branch_offset(Label* L, bool jump_elimination_allowed) { |
963 int32_t target_pos; | 963 int32_t target_pos; |
964 | 964 |
965 if (L->is_bound()) { | 965 if (L->is_bound()) { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1080 BlockTrampolinePoolScope block_trampoline_pool(this); | 1080 BlockTrampolinePoolScope block_trampoline_pool(this); |
1081 GenInstrImmediate(BNE, rs, rt, offset); | 1081 GenInstrImmediate(BNE, rs, rt, offset); |
1082 BlockTrampolinePoolFor(1); // For associated delay slot. | 1082 BlockTrampolinePoolFor(1); // For associated delay slot. |
1083 } | 1083 } |
1084 | 1084 |
1085 | 1085 |
1086 void Assembler::j(int32_t target) { | 1086 void Assembler::j(int32_t target) { |
1087 #if DEBUG | 1087 #if DEBUG |
1088 // Get pc of delay slot. | 1088 // Get pc of delay slot. |
1089 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); | 1089 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); |
1090 bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0; | 1090 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> |
| 1091 (kImm26Bits + kImmFieldShift)) == 0; |
1091 ASSERT(in_range && ((target & 3) == 0)); | 1092 ASSERT(in_range && ((target & 3) == 0)); |
1092 #endif | 1093 #endif |
1093 GenInstrJump(J, target >> 2); | 1094 GenInstrJump(J, target >> 2); |
1094 } | 1095 } |
1095 | 1096 |
1096 | 1097 |
1097 void Assembler::jr(Register rs) { | 1098 void Assembler::jr(Register rs) { |
1098 BlockTrampolinePoolScope block_trampoline_pool(this); | 1099 BlockTrampolinePoolScope block_trampoline_pool(this); |
1099 if (rs.is(ra)) { | 1100 if (rs.is(ra)) { |
1100 positions_recorder()->WriteRecordedPositions(); | 1101 positions_recorder()->WriteRecordedPositions(); |
1101 } | 1102 } |
1102 GenInstrRegister(SPECIAL, rs, zero_reg, zero_reg, 0, JR); | 1103 GenInstrRegister(SPECIAL, rs, zero_reg, zero_reg, 0, JR); |
1103 BlockTrampolinePoolFor(1); // For associated delay slot. | 1104 BlockTrampolinePoolFor(1); // For associated delay slot. |
1104 } | 1105 } |
1105 | 1106 |
1106 | 1107 |
1107 void Assembler::jal(int32_t target) { | 1108 void Assembler::jal(int32_t target) { |
1108 #ifdef DEBUG | 1109 #ifdef DEBUG |
1109 // Get pc of delay slot. | 1110 // Get pc of delay slot. |
1110 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); | 1111 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); |
1111 bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0; | 1112 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> |
| 1113 (kImm26Bits + kImmFieldShift)) == 0; |
1112 ASSERT(in_range && ((target & 3) == 0)); | 1114 ASSERT(in_range && ((target & 3) == 0)); |
1113 #endif | 1115 #endif |
1114 positions_recorder()->WriteRecordedPositions(); | 1116 positions_recorder()->WriteRecordedPositions(); |
1115 GenInstrJump(JAL, target >> 2); | 1117 GenInstrJump(JAL, target >> 2); |
1116 } | 1118 } |
1117 | 1119 |
1118 | 1120 |
1119 void Assembler::jalr(Register rs, Register rd) { | 1121 void Assembler::jalr(Register rs, Register rd) { |
1120 BlockTrampolinePoolScope block_trampoline_pool(this); | 1122 BlockTrampolinePoolScope block_trampoline_pool(this); |
1121 positions_recorder()->WriteRecordedPositions(); | 1123 positions_recorder()->WriteRecordedPositions(); |
1122 GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR); | 1124 GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR); |
1123 BlockTrampolinePoolFor(1); // For associated delay slot. | 1125 BlockTrampolinePoolFor(1); // For associated delay slot. |
1124 } | 1126 } |
1125 | 1127 |
1126 | 1128 |
1127 void Assembler::j_or_jr(int32_t target, Register rs) { | 1129 void Assembler::j_or_jr(int32_t target, Register rs) { |
1128 // Get pc of delay slot. | 1130 // Get pc of delay slot. |
1129 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); | 1131 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); |
1130 bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0; | 1132 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> |
1131 | 1133 (kImm26Bits + kImmFieldShift)) == 0; |
1132 if (in_range) { | 1134 if (in_range) { |
1133 j(target); | 1135 j(target); |
1134 } else { | 1136 } else { |
1135 jr(t9); | 1137 jr(t9); |
1136 } | 1138 } |
1137 } | 1139 } |
1138 | 1140 |
1139 | 1141 |
1140 void Assembler::jal_or_jalr(int32_t target, Register rs) { | 1142 void Assembler::jal_or_jalr(int32_t target, Register rs) { |
1141 // Get pc of delay slot. | 1143 // Get pc of delay slot. |
1142 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); | 1144 uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); |
1143 bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0; | 1145 bool in_range = (ipc ^ static_cast<uint32_t>(target) >> |
1144 | 1146 (kImm26Bits+kImmFieldShift)) == 0; |
1145 if (in_range) { | 1147 if (in_range) { |
1146 jal(target); | 1148 jal(target); |
1147 } else { | 1149 } else { |
1148 jalr(t9); | 1150 jalr(t9); |
1149 } | 1151 } |
1150 } | 1152 } |
1151 | 1153 |
1152 | 1154 |
1153 //-------Data-processing-instructions--------- | 1155 //-------Data-processing-instructions--------- |
1154 | 1156 |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1893 instr_lui &= ~kImm16Mask; | 1895 instr_lui &= ~kImm16Mask; |
1894 instr_ori &= ~kImm16Mask; | 1896 instr_ori &= ~kImm16Mask; |
1895 | 1897 |
1896 instr_at_put(pc + 0 * Assembler::kInstrSize, | 1898 instr_at_put(pc + 0 * Assembler::kInstrSize, |
1897 instr_lui | ((imm >> kLuiShift) & kImm16Mask)); | 1899 instr_lui | ((imm >> kLuiShift) & kImm16Mask)); |
1898 instr_at_put(pc + 1 * Assembler::kInstrSize, | 1900 instr_at_put(pc + 1 * Assembler::kInstrSize, |
1899 instr_ori | (imm & kImm16Mask)); | 1901 instr_ori | (imm & kImm16Mask)); |
1900 return 2; // Number of instructions patched. | 1902 return 2; // Number of instructions patched. |
1901 } else { | 1903 } else { |
1902 uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; | 1904 uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; |
1903 if ((int32_t)imm28 == kEndOfJumpChain) { | 1905 if (static_cast<int32_t>(imm28) == kEndOfJumpChain) { |
1904 return 0; // Number of instructions patched. | 1906 return 0; // Number of instructions patched. |
1905 } | 1907 } |
1906 imm28 += pc_delta; | 1908 imm28 += pc_delta; |
1907 imm28 &= kImm28Mask; | 1909 imm28 &= kImm28Mask; |
1908 ASSERT((imm28 & 3) == 0); | 1910 ASSERT((imm28 & 3) == 0); |
1909 | 1911 |
1910 instr &= ~kImm26Mask; | 1912 instr &= ~kImm26Mask; |
1911 uint32_t imm26 = imm28 >> 2; | 1913 uint32_t imm26 = imm28 >> 2; |
1912 ASSERT(is_uint26(imm26)); | 1914 ASSERT(is_uint26(imm26)); |
1913 | 1915 |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2143 // 256 MB page. Note that with the jal/j instructions, we do not need to | 2145 // 256 MB page. Note that with the jal/j instructions, we do not need to |
2144 // load the register, but that code is left, since it makes it easy to | 2146 // load the register, but that code is left, since it makes it easy to |
2145 // revert this process. A further optimization could try replacing the | 2147 // revert this process. A further optimization could try replacing the |
2146 // li sequence with nops. | 2148 // li sequence with nops. |
2147 // This optimization can only be applied if the rt-code from instr2 is the | 2149 // This optimization can only be applied if the rt-code from instr2 is the |
2148 // register used for the jalr/jr. Finally, we have to skip 'jr ra', which is | 2150 // register used for the jalr/jr. Finally, we have to skip 'jr ra', which is |
2149 // mips return. Occasionally this lands after an li(). | 2151 // mips return. Occasionally this lands after an li(). |
2150 | 2152 |
2151 Instr instr3 = instr_at(pc + 2 * kInstrSize); | 2153 Instr instr3 = instr_at(pc + 2 * kInstrSize); |
2152 uint32_t ipc = reinterpret_cast<uint32_t>(pc + 3 * kInstrSize); | 2154 uint32_t ipc = reinterpret_cast<uint32_t>(pc + 3 * kInstrSize); |
2153 bool in_range = | 2155 bool in_range = (ipc ^ static_cast<uint32_t>(itarget) >> |
2154 ((uint32_t)(ipc ^ itarget) >> (kImm26Bits + kImmFieldShift)) == 0; | 2156 (kImm26Bits + kImmFieldShift)) == 0; |
2155 uint32_t target_field = (uint32_t)(itarget & kJumpAddrMask) >> kImmFieldShift; | 2157 uint32_t target_field = |
| 2158 static_cast<uint32_t>(itarget & kJumpAddrMask) >>kImmFieldShift; |
2156 bool patched_jump = false; | 2159 bool patched_jump = false; |
2157 | 2160 |
2158 #ifndef ALLOW_JAL_IN_BOUNDARY_REGION | 2161 #ifndef ALLOW_JAL_IN_BOUNDARY_REGION |
2159 // This is a workaround to the 24k core E156 bug (affect some 34k cores also). | 2162 // This is a workaround to the 24k core E156 bug (affect some 34k cores also). |
2160 // Since the excluded space is only 64KB out of 256MB (0.02 %), we will just | 2163 // Since the excluded space is only 64KB out of 256MB (0.02 %), we will just |
2161 // apply this workaround for all cores so we don't have to identify the core. | 2164 // apply this workaround for all cores so we don't have to identify the core. |
2162 if (in_range) { | 2165 if (in_range) { |
2163 // The 24k core E156 bug has some very specific requirements, we only check | 2166 // The 24k core E156 bug has some very specific requirements, we only check |
2164 // the most simple one: if the address of the delay slot instruction is in | 2167 // the most simple one: if the address of the delay slot instruction is in |
2165 // the first or last 32 KB of the 256 MB segment. | 2168 // the first or last 32 KB of the 256 MB segment. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2240 } | 2243 } |
2241 | 2244 |
2242 if (patched) { | 2245 if (patched) { |
2243 CPU::FlushICache(pc+2, sizeof(Address)); | 2246 CPU::FlushICache(pc+2, sizeof(Address)); |
2244 } | 2247 } |
2245 } | 2248 } |
2246 | 2249 |
2247 } } // namespace v8::internal | 2250 } } // namespace v8::internal |
2248 | 2251 |
2249 #endif // V8_TARGET_ARCH_MIPS | 2252 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |