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 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 void MacroAssembler::VmovLow(DwVfpRegister dst, Register src) { | 1074 void MacroAssembler::VmovLow(DwVfpRegister dst, Register src) { |
1075 if (dst.code() < 16) { | 1075 if (dst.code() < 16) { |
1076 const LowDwVfpRegister loc = LowDwVfpRegister::from_code(dst.code()); | 1076 const LowDwVfpRegister loc = LowDwVfpRegister::from_code(dst.code()); |
1077 vmov(loc.low(), src); | 1077 vmov(loc.low(), src); |
1078 } else { | 1078 } else { |
1079 vmov(dst, VmovIndexLo, src); | 1079 vmov(dst, VmovIndexLo, src); |
1080 } | 1080 } |
1081 } | 1081 } |
1082 | 1082 |
1083 void MacroAssembler::VmovExtended(Register dst, int src_code) { | 1083 void MacroAssembler::VmovExtended(Register dst, int src_code) { |
1084 DCHECK_LE(32, src_code); | 1084 DCHECK_LE(SwVfpRegister::kMaxNumRegisters, src_code); |
1085 DCHECK_GT(64, src_code); | 1085 DCHECK_GT(SwVfpRegister::kMaxNumRegisters * 2, src_code); |
1086 if (src_code & 0x1) { | 1086 if (src_code & 0x1) { |
1087 VmovHigh(dst, DwVfpRegister::from_code(src_code / 2)); | 1087 VmovHigh(dst, DwVfpRegister::from_code(src_code / 2)); |
1088 } else { | 1088 } else { |
1089 VmovLow(dst, DwVfpRegister::from_code(src_code / 2)); | 1089 VmovLow(dst, DwVfpRegister::from_code(src_code / 2)); |
1090 } | 1090 } |
1091 } | 1091 } |
1092 | 1092 |
1093 void MacroAssembler::VmovExtended(int dst_code, Register src) { | 1093 void MacroAssembler::VmovExtended(int dst_code, Register src) { |
1094 DCHECK_LE(32, dst_code); | 1094 DCHECK_LE(SwVfpRegister::kMaxNumRegisters, dst_code); |
1095 DCHECK_GT(64, dst_code); | 1095 DCHECK_GT(SwVfpRegister::kMaxNumRegisters * 2, dst_code); |
1096 if (dst_code & 0x1) { | 1096 if (dst_code & 0x1) { |
1097 VmovHigh(DwVfpRegister::from_code(dst_code / 2), src); | 1097 VmovHigh(DwVfpRegister::from_code(dst_code / 2), src); |
1098 } else { | 1098 } else { |
1099 VmovLow(DwVfpRegister::from_code(dst_code / 2), src); | 1099 VmovLow(DwVfpRegister::from_code(dst_code / 2), src); |
1100 } | 1100 } |
1101 } | 1101 } |
1102 | 1102 |
1103 void MacroAssembler::VmovExtended(int dst_code, int src_code, | 1103 void MacroAssembler::VmovExtended(int dst_code, int src_code, |
1104 Register scratch) { | 1104 Register scratch) { |
1105 if (src_code < 32 && dst_code < 32) { | 1105 if (src_code < SwVfpRegister::kMaxNumRegisters && |
| 1106 dst_code < SwVfpRegister::kMaxNumRegisters) { |
1106 // src and dst are both s-registers. | 1107 // src and dst are both s-registers. |
1107 vmov(SwVfpRegister::from_code(dst_code), | 1108 vmov(SwVfpRegister::from_code(dst_code), |
1108 SwVfpRegister::from_code(src_code)); | 1109 SwVfpRegister::from_code(src_code)); |
1109 } else if (src_code < 32) { | 1110 } else if (src_code < SwVfpRegister::kMaxNumRegisters) { |
1110 // src is an s-register. | 1111 // src is an s-register. |
1111 vmov(scratch, SwVfpRegister::from_code(src_code)); | 1112 vmov(scratch, SwVfpRegister::from_code(src_code)); |
1112 VmovExtended(dst_code, scratch); | 1113 VmovExtended(dst_code, scratch); |
1113 } else if (dst_code < 32) { | 1114 } else if (dst_code < SwVfpRegister::kMaxNumRegisters) { |
1114 // dst is an s-register. | 1115 // dst is an s-register. |
1115 VmovExtended(scratch, src_code); | 1116 VmovExtended(scratch, src_code); |
1116 vmov(SwVfpRegister::from_code(dst_code), scratch); | 1117 vmov(SwVfpRegister::from_code(dst_code), scratch); |
1117 } else { | 1118 } else { |
1118 // Neither src or dst are s-registers. | 1119 // Neither src or dst are s-registers. |
1119 DCHECK_GT(64, src_code); | 1120 DCHECK_GT(SwVfpRegister::kMaxNumRegisters * 2, src_code); |
1120 DCHECK_GT(64, dst_code); | 1121 DCHECK_GT(SwVfpRegister::kMaxNumRegisters * 2, dst_code); |
1121 VmovExtended(scratch, src_code); | 1122 VmovExtended(scratch, src_code); |
1122 VmovExtended(dst_code, scratch); | 1123 VmovExtended(dst_code, scratch); |
1123 } | 1124 } |
1124 } | 1125 } |
1125 | 1126 |
1126 void MacroAssembler::VmovExtended(int dst_code, const MemOperand& src, | 1127 void MacroAssembler::VmovExtended(int dst_code, const MemOperand& src, |
1127 Register scratch) { | 1128 Register scratch) { |
1128 if (dst_code >= 32) { | 1129 if (dst_code >= SwVfpRegister::kMaxNumRegisters) { |
1129 ldr(scratch, src); | 1130 ldr(scratch, src); |
1130 VmovExtended(dst_code, scratch); | 1131 VmovExtended(dst_code, scratch); |
1131 } else { | 1132 } else { |
1132 vldr(SwVfpRegister::from_code(dst_code), src); | 1133 vldr(SwVfpRegister::from_code(dst_code), src); |
1133 } | 1134 } |
1134 } | 1135 } |
1135 | 1136 |
1136 void MacroAssembler::VmovExtended(const MemOperand& dst, int src_code, | 1137 void MacroAssembler::VmovExtended(const MemOperand& dst, int src_code, |
1137 Register scratch) { | 1138 Register scratch) { |
1138 if (src_code >= 32) { | 1139 if (src_code >= SwVfpRegister::kMaxNumRegisters) { |
1139 VmovExtended(scratch, src_code); | 1140 VmovExtended(scratch, src_code); |
1140 str(scratch, dst); | 1141 str(scratch, dst); |
1141 } else { | 1142 } else { |
1142 vstr(SwVfpRegister::from_code(src_code), dst); | 1143 vstr(SwVfpRegister::from_code(src_code), dst); |
1143 } | 1144 } |
1144 } | 1145 } |
1145 | 1146 |
| 1147 void MacroAssembler::ExtractLane(Register dst, QwNeonRegister src, |
| 1148 NeonDataType dt, int lane) { |
| 1149 int bytes_per_lane = dt & NeonDataTypeSizeMask; // 1, 2, 4 |
| 1150 int log2_bytes_per_lane = bytes_per_lane / 2; // 0, 1, 2 |
| 1151 int byte = lane << log2_bytes_per_lane; |
| 1152 int double_word = byte >> kDoubleSizeLog2; |
| 1153 int double_byte = byte & (kDoubleSize - 1); |
| 1154 int double_lane = double_byte >> log2_bytes_per_lane; |
| 1155 DwVfpRegister double_source = |
| 1156 DwVfpRegister::from_code(src.code() * 2 + double_word); |
| 1157 vmov(dt, dst, double_source, double_lane); |
| 1158 } |
| 1159 |
| 1160 void MacroAssembler::ExtractLane(SwVfpRegister dst, QwNeonRegister src, |
| 1161 Register scratch, int lane) { |
| 1162 int s_code = src.code() * 4 + lane; |
| 1163 VmovExtended(dst.code(), s_code, scratch); |
| 1164 } |
| 1165 |
| 1166 void MacroAssembler::ReplaceLane(QwNeonRegister dst, QwNeonRegister src, |
| 1167 Register src_lane, NeonDataType dt, int lane) { |
| 1168 Move(dst, src); |
| 1169 int bytes_per_lane = dt & NeonDataTypeSizeMask; // 1, 2, 4 |
| 1170 int log2_bytes_per_lane = bytes_per_lane / 2; // 0, 1, 2 |
| 1171 int byte = lane << log2_bytes_per_lane; |
| 1172 int double_word = byte >> kDoubleSizeLog2; |
| 1173 int double_byte = byte & (kDoubleSize - 1); |
| 1174 int double_lane = double_byte >> log2_bytes_per_lane; |
| 1175 DwVfpRegister double_dst = |
| 1176 DwVfpRegister::from_code(dst.code() * 2 + double_word); |
| 1177 vmov(dt, double_dst, double_lane, src_lane); |
| 1178 } |
| 1179 |
| 1180 void MacroAssembler::ReplaceLane(QwNeonRegister dst, QwNeonRegister src, |
| 1181 SwVfpRegister src_lane, Register scratch, |
| 1182 int lane) { |
| 1183 Move(dst, src); |
| 1184 int s_code = dst.code() * 4 + lane; |
| 1185 VmovExtended(s_code, src_lane.code(), scratch); |
| 1186 } |
| 1187 |
1146 void MacroAssembler::LslPair(Register dst_low, Register dst_high, | 1188 void MacroAssembler::LslPair(Register dst_low, Register dst_high, |
1147 Register src_low, Register src_high, | 1189 Register src_low, Register src_high, |
1148 Register scratch, Register shift) { | 1190 Register scratch, Register shift) { |
1149 DCHECK(!AreAliased(dst_high, src_low)); | 1191 DCHECK(!AreAliased(dst_high, src_low)); |
1150 DCHECK(!AreAliased(dst_high, shift)); | 1192 DCHECK(!AreAliased(dst_high, shift)); |
1151 | 1193 |
1152 Label less_than_32; | 1194 Label less_than_32; |
1153 Label done; | 1195 Label done; |
1154 rsb(scratch, shift, Operand(32), SetCC); | 1196 rsb(scratch, shift, Operand(32), SetCC); |
1155 b(gt, &less_than_32); | 1197 b(gt, &less_than_32); |
(...skipping 2735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3891 } | 3933 } |
3892 } | 3934 } |
3893 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); | 3935 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); |
3894 add(result, result, Operand(dividend, LSR, 31)); | 3936 add(result, result, Operand(dividend, LSR, 31)); |
3895 } | 3937 } |
3896 | 3938 |
3897 } // namespace internal | 3939 } // namespace internal |
3898 } // namespace v8 | 3940 } // namespace v8 |
3899 | 3941 |
3900 #endif // V8_TARGET_ARCH_ARM | 3942 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |