OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/division-by-constant.h" | 10 #include "src/base/division-by-constant.h" |
(...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 | 1044 |
1045 void MacroAssembler::VmovLow(DwVfpRegister dst, Register src) { | 1045 void MacroAssembler::VmovLow(DwVfpRegister dst, Register src) { |
1046 if (dst.code() < 16) { | 1046 if (dst.code() < 16) { |
1047 const LowDwVfpRegister loc = LowDwVfpRegister::from_code(dst.code()); | 1047 const LowDwVfpRegister loc = LowDwVfpRegister::from_code(dst.code()); |
1048 vmov(loc.low(), src); | 1048 vmov(loc.low(), src); |
1049 } else { | 1049 } else { |
1050 vmov(dst, VmovIndexLo, src); | 1050 vmov(dst, VmovIndexLo, src); |
1051 } | 1051 } |
1052 } | 1052 } |
1053 | 1053 |
1054 void MacroAssembler::VmovExtended(Register dst, int src_code) { | 1054 void MacroAssembler::VmovExtended(int dst_code, int src_code) { |
1055 DCHECK_LE(32, src_code); | |
1056 DCHECK_GT(64, src_code); | |
1057 if (src_code & 0x1) { | |
1058 VmovHigh(dst, DwVfpRegister::from_code(src_code / 2)); | |
1059 } else { | |
1060 VmovLow(dst, DwVfpRegister::from_code(src_code / 2)); | |
1061 } | |
1062 } | |
1063 | |
1064 void MacroAssembler::VmovExtended(int dst_code, Register src) { | |
1065 DCHECK_LE(32, dst_code); | |
1066 DCHECK_GT(64, dst_code); | |
1067 if (dst_code & 0x1) { | |
1068 VmovHigh(DwVfpRegister::from_code(dst_code / 2), src); | |
1069 } else { | |
1070 VmovLow(DwVfpRegister::from_code(dst_code / 2), src); | |
1071 } | |
1072 } | |
1073 | |
1074 void MacroAssembler::VmovExtended(int dst_code, int src_code, | |
1075 Register scratch) { | |
1076 if (src_code < 32 && dst_code < 32) { | 1055 if (src_code < 32 && dst_code < 32) { |
1077 // src and dst are both s-registers. | 1056 // src and dst are both s-registers. |
1078 vmov(SwVfpRegister::from_code(dst_code), | 1057 vmov(SwVfpRegister::from_code(dst_code), |
1079 SwVfpRegister::from_code(src_code)); | 1058 SwVfpRegister::from_code(src_code)); |
1080 } else if (src_code < 32) { | 1059 } else if (src_code < 32) { |
1081 // src is an s-register. | 1060 // src is s-register, dst is in high d-register. Move dst into scratch |
1082 vmov(scratch, SwVfpRegister::from_code(src_code)); | 1061 // d-register to do the s-register move, then back. |
1083 VmovExtended(dst_code, scratch); | 1062 DCHECK_GT(64, dst_code); |
| 1063 DwVfpRegister dst_reg = DwVfpRegister::from_code(dst_code / 2); |
| 1064 int dst_s_code = kScratchDoubleReg.low().code() + (dst_code & 1); |
| 1065 vmov(kScratchDoubleReg, dst_reg); |
| 1066 vmov(SwVfpRegister::from_code(dst_s_code), |
| 1067 SwVfpRegister::from_code(src_code)); |
| 1068 vmov(dst_reg, kScratchDoubleReg); |
1084 } else if (dst_code < 32) { | 1069 } else if (dst_code < 32) { |
1085 // dst is an s-register. | 1070 // src is in high d-register, dst is an s-register. Move src into scratch |
1086 VmovExtended(scratch, src_code); | 1071 // d-register, do the s-register move. |
1087 vmov(SwVfpRegister::from_code(dst_code), scratch); | 1072 DCHECK_GT(64, src_code); |
| 1073 DwVfpRegister src_reg = DwVfpRegister::from_code(src_code / 2); |
| 1074 int src_s_code = kScratchDoubleReg.low().code() + (src_code & 1); |
| 1075 vmov(kScratchDoubleReg, src_reg); |
| 1076 vmov(SwVfpRegister::from_code(dst_code), |
| 1077 SwVfpRegister::from_code(src_s_code)); |
1088 } else { | 1078 } else { |
1089 // Neither src or dst are s-registers. | 1079 // src and dst are in high d-registers. Move both into free registers, |
| 1080 // do the s-register move, then move dst back. |
1090 DCHECK_GT(64, src_code); | 1081 DCHECK_GT(64, src_code); |
1091 DCHECK_GT(64, dst_code); | 1082 DCHECK_GT(64, dst_code); |
1092 VmovExtended(scratch, src_code); | 1083 DwVfpRegister dst_reg = DwVfpRegister::from_code(dst_code / 2); |
1093 VmovExtended(dst_code, scratch); | 1084 DwVfpRegister src_reg = DwVfpRegister::from_code(src_code / 2); |
| 1085 int dst_s_code = kScratchDoubleReg.low().code() + (dst_code & 1); |
| 1086 int src_s_code = kDoubleRegZero.low().code() + (src_code & 1); |
| 1087 vmov(kScratchDoubleReg, dst_reg); |
| 1088 vmov(kDoubleRegZero, src_reg); |
| 1089 vmov(SwVfpRegister::from_code(dst_s_code), |
| 1090 SwVfpRegister::from_code(src_s_code)); |
| 1091 vmov(dst_reg, kScratchDoubleReg); |
| 1092 vmov(kDoubleRegZero, 0.0); // restore zero register |
1094 } | 1093 } |
1095 } | 1094 } |
1096 | 1095 |
1097 void MacroAssembler::VmovExtended(int dst_code, const MemOperand& src, | 1096 void MacroAssembler::VmovExtended(int dst_code, const MemOperand& src) { |
1098 Register scratch) { | 1097 if (dst_code < 32) { |
1099 if (dst_code >= 32) { | 1098 vldr(SwVfpRegister::from_code(dst_code), src); |
1100 ldr(scratch, src); | |
1101 VmovExtended(dst_code, scratch); | |
1102 } else { | 1099 } else { |
1103 vldr(SwVfpRegister::from_code(dst_code), src); | 1100 // dst is in high d-register, move it down, load src, then move it back up. |
| 1101 DCHECK_GT(64, dst_code); |
| 1102 DwVfpRegister dst_reg = DwVfpRegister::from_code(dst_code / 2); |
| 1103 int dst_s_code = kScratchDoubleReg.low().code() + (dst_code & 1); |
| 1104 vmov(kScratchDoubleReg, dst_reg); |
| 1105 vldr(SwVfpRegister::from_code(dst_s_code), src); |
| 1106 vmov(dst_reg, kScratchDoubleReg); |
| 1107 } |
| 1108 } |
| 1109 void MacroAssembler::VmovExtended(const MemOperand& dst, int src_code) { |
| 1110 if (src_code < 32) { |
| 1111 vstr(SwVfpRegister::from_code(src_code), dst); |
| 1112 } else { |
| 1113 // src is in high d-register, move it down, store src. |
| 1114 DCHECK_GT(64, src_code); |
| 1115 DwVfpRegister src_reg = DwVfpRegister::from_code(src_code / 2); |
| 1116 int src_s_code = kScratchDoubleReg.low().code() + (src_code & 1); |
| 1117 vmov(kScratchDoubleReg, src_reg); |
| 1118 vstr(SwVfpRegister::from_code(src_s_code), dst); |
1104 } | 1119 } |
1105 } | 1120 } |
1106 | 1121 |
1107 void MacroAssembler::VmovExtended(const MemOperand& dst, int src_code, | 1122 void MacroAssembler::VswpExtended(int dst_code, int src_code) { |
1108 Register scratch) { | 1123 if (src_code < 32 && dst_code < 32) { |
1109 if (src_code >= 32) { | 1124 // src and dst are both s-registers. |
1110 VmovExtended(scratch, src_code); | 1125 vmov(kScratchDoubleReg.low(), SwVfpRegister::from_code(dst_code)); |
1111 str(scratch, dst); | 1126 vmov(SwVfpRegister::from_code(dst_code), |
| 1127 SwVfpRegister::from_code(src_code)); |
| 1128 vmov(SwVfpRegister::from_code(src_code), kScratchDoubleReg.low()); |
| 1129 } else if (src_code < 32) { |
| 1130 // src is s-register, dst is in high d-register. Move dst into scratch |
| 1131 // d-register to do the s-register swap, then back. |
| 1132 DCHECK_GT(64, dst_code); |
| 1133 DwVfpRegister dst_reg = DwVfpRegister::from_code(dst_code / 2); |
| 1134 int dst_s_code = kScratchDoubleReg.low().code() + (dst_code & 1); |
| 1135 int dst_s_temp = kDoubleRegZero.low().code() + (dst_code & 1); |
| 1136 vmov(kScratchDoubleReg, dst_reg); |
| 1137 vmov(kDoubleRegZero, dst_reg); |
| 1138 vmov(SwVfpRegister::from_code(dst_s_code), |
| 1139 SwVfpRegister::from_code(src_code)); |
| 1140 vmov(dst_reg, kScratchDoubleReg); |
| 1141 vmov(SwVfpRegister::from_code(src_code), |
| 1142 SwVfpRegister::from_code(dst_s_temp)); |
| 1143 vmov(kDoubleRegZero, 0.0); // restore zero register |
| 1144 } else if (dst_code < 32) { |
| 1145 // src is in high d-register, dst is an s-register. Move src into scratch |
| 1146 // d-register, do the s-register swap. |
| 1147 DCHECK_GT(64, src_code); |
| 1148 DwVfpRegister src_reg = DwVfpRegister::from_code(src_code / 2); |
| 1149 int src_s_code = kScratchDoubleReg.low().code() + (src_code & 1); |
| 1150 int src_s_temp = kDoubleRegZero.low().code() + (src_code & 1); |
| 1151 vmov(kScratchDoubleReg, src_reg); |
| 1152 vmov(kDoubleRegZero, src_reg); |
| 1153 vmov(SwVfpRegister::from_code(src_s_code), |
| 1154 SwVfpRegister::from_code(dst_code)); |
| 1155 vmov(src_reg, kScratchDoubleReg); |
| 1156 vmov(SwVfpRegister::from_code(dst_code), |
| 1157 SwVfpRegister::from_code(src_s_temp)); |
| 1158 vmov(kDoubleRegZero, 0.0); // restore zero register |
1112 } else { | 1159 } else { |
1113 vstr(SwVfpRegister::from_code(src_code), dst); | 1160 // src and dst are in high d-registers. Move both into free registers, |
| 1161 // do the s-register swap, then move both back. |
| 1162 DCHECK_GT(64, src_code); |
| 1163 DCHECK_GT(64, dst_code); |
| 1164 DwVfpRegister dst_reg = DwVfpRegister::from_code(dst_code / 2); |
| 1165 DwVfpRegister src_reg = DwVfpRegister::from_code(src_code / 2); |
| 1166 int dst_s_code = kScratchDoubleReg.low().code() + (dst_code & 1); |
| 1167 int src_s_code = kDoubleRegZero.low().code() + (src_code & 1); |
| 1168 vmov(kScratchDoubleReg, dst_reg); |
| 1169 vmov(kDoubleRegZero, src_reg); |
| 1170 vmov(SwVfpRegister::from_code(src_s_code ^ 1), |
| 1171 SwVfpRegister::from_code(dst_s_code)); |
| 1172 vmov(SwVfpRegister::from_code(dst_s_code), |
| 1173 SwVfpRegister::from_code(src_s_code)); |
| 1174 vmov(dst_reg, kScratchDoubleReg); |
| 1175 vmov(kScratchDoubleReg, src_reg); |
| 1176 vmov(SwVfpRegister::from_code(dst_s_code), |
| 1177 SwVfpRegister::from_code(src_s_code ^ 1)); |
| 1178 vmov(src_reg, kScratchDoubleReg); |
| 1179 vmov(kDoubleRegZero, 0.0); // restore zero register |
1114 } | 1180 } |
1115 } | 1181 } |
1116 | 1182 |
| 1183 void MacroAssembler::VswpExtended(const MemOperand& dst, int src_code) { |
| 1184 if (src_code < 32) { |
| 1185 vldr(kScratchDoubleReg.low(), dst); |
| 1186 vstr(SwVfpRegister::from_code(src_code), dst); |
| 1187 vmov(SwVfpRegister::from_code(src_code), kScratchDoubleReg.low()); |
| 1188 } else { |
| 1189 // src is in high d-register, move it down, do the swap, move src back up. |
| 1190 DCHECK_GT(64, src_code); |
| 1191 DwVfpRegister src_reg = DwVfpRegister::from_code(src_code / 2); |
| 1192 int src_s_code = kScratchDoubleReg.low().code() + (src_code & 1); |
| 1193 vmov(kScratchDoubleReg, src_reg); |
| 1194 vldr(kDoubleRegZero.low(), dst); |
| 1195 vstr(SwVfpRegister::from_code(src_s_code), dst); |
| 1196 vmov(SwVfpRegister::from_code(src_s_code), kDoubleRegZero.low()); |
| 1197 vmov(src_reg, kScratchDoubleReg); |
| 1198 vmov(kDoubleRegZero, 0.0); // restore zero register |
| 1199 } |
| 1200 } |
| 1201 |
1117 void MacroAssembler::LslPair(Register dst_low, Register dst_high, | 1202 void MacroAssembler::LslPair(Register dst_low, Register dst_high, |
1118 Register src_low, Register src_high, | 1203 Register src_low, Register src_high, |
1119 Register scratch, Register shift) { | 1204 Register scratch, Register shift) { |
1120 DCHECK(!AreAliased(dst_high, src_low)); | 1205 DCHECK(!AreAliased(dst_high, src_low)); |
1121 DCHECK(!AreAliased(dst_high, shift)); | 1206 DCHECK(!AreAliased(dst_high, shift)); |
1122 | 1207 |
1123 Label less_than_32; | 1208 Label less_than_32; |
1124 Label done; | 1209 Label done; |
1125 rsb(scratch, shift, Operand(32), SetCC); | 1210 rsb(scratch, shift, Operand(32), SetCC); |
1126 b(gt, &less_than_32); | 1211 b(gt, &less_than_32); |
(...skipping 2867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3994 } | 4079 } |
3995 } | 4080 } |
3996 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); | 4081 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); |
3997 add(result, result, Operand(dividend, LSR, 31)); | 4082 add(result, result, Operand(dividend, LSR, 31)); |
3998 } | 4083 } |
3999 | 4084 |
4000 } // namespace internal | 4085 } // namespace internal |
4001 } // namespace v8 | 4086 } // namespace v8 |
4002 | 4087 |
4003 #endif // V8_TARGET_ARCH_ARM | 4088 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |