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_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 #include "src/base/division-by-constant.h" | 9 #include "src/base/division-by-constant.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 } | 1204 } |
1205 | 1205 |
1206 | 1206 |
1207 // Do 64-bit load from unaligned address. Note this only handles | 1207 // Do 64-bit load from unaligned address. Note this only handles |
1208 // the specific case of 32-bit aligned, but not 64-bit aligned. | 1208 // the specific case of 32-bit aligned, but not 64-bit aligned. |
1209 void MacroAssembler::Uld(Register rd, const MemOperand& rs, Register scratch) { | 1209 void MacroAssembler::Uld(Register rd, const MemOperand& rs, Register scratch) { |
1210 // Assert fail if the offset from start of object IS actually aligned. | 1210 // Assert fail if the offset from start of object IS actually aligned. |
1211 // ONLY use with known misalignment, since there is performance cost. | 1211 // ONLY use with known misalignment, since there is performance cost. |
1212 DCHECK((rs.offset() + kHeapObjectTag) & (kPointerSize - 1)); | 1212 DCHECK((rs.offset() + kHeapObjectTag) & (kPointerSize - 1)); |
1213 // TODO(plind): endian dependency. | 1213 // TODO(plind): endian dependency. |
1214 lwu(rd, rs); | 1214 if (kArchEndian == kLittle) { |
1215 lw(scratch, MemOperand(rs.rm(), rs.offset() + kPointerSize / 2)); | 1215 lwu(rd, rs); |
1216 dsll32(scratch, scratch, 0); | 1216 lw(scratch, MemOperand(rs.rm(), rs.offset() + kPointerSize / 2)); |
| 1217 dsll32(scratch, scratch, 0); |
| 1218 } else { |
| 1219 lw(rd, rs); |
| 1220 lwu(scratch, MemOperand(rs.rm(), rs.offset() + kPointerSize / 2)); |
| 1221 dsll32(rd, rd, 0); |
| 1222 } |
1217 Daddu(rd, rd, scratch); | 1223 Daddu(rd, rd, scratch); |
1218 } | 1224 } |
1219 | 1225 |
1220 | 1226 |
1221 // Do 64-bit store to unaligned address. Note this only handles | 1227 // Do 64-bit store to unaligned address. Note this only handles |
1222 // the specific case of 32-bit aligned, but not 64-bit aligned. | 1228 // the specific case of 32-bit aligned, but not 64-bit aligned. |
1223 void MacroAssembler::Usd(Register rd, const MemOperand& rs, Register scratch) { | 1229 void MacroAssembler::Usd(Register rd, const MemOperand& rs, Register scratch) { |
1224 // Assert fail if the offset from start of object IS actually aligned. | 1230 // Assert fail if the offset from start of object IS actually aligned. |
1225 // ONLY use with known misalignment, since there is performance cost. | 1231 // ONLY use with known misalignment, since there is performance cost. |
1226 DCHECK((rs.offset() + kHeapObjectTag) & (kPointerSize - 1)); | 1232 DCHECK((rs.offset() + kHeapObjectTag) & (kPointerSize - 1)); |
1227 // TODO(plind): endian dependency. | 1233 // TODO(plind): endian dependency. |
1228 sw(rd, rs); | 1234 if (kArchEndian == kLittle) { |
1229 dsrl32(scratch, rd, 0); | 1235 sw(rd, rs); |
1230 sw(scratch, MemOperand(rs.rm(), rs.offset() + kPointerSize / 2)); | 1236 dsrl32(scratch, rd, 0); |
| 1237 sw(scratch, MemOperand(rs.rm(), rs.offset() + kPointerSize / 2)); |
| 1238 } else { |
| 1239 sw(rd, MemOperand(rs.rm(), rs.offset() + kPointerSize / 2)); |
| 1240 dsrl32(scratch, rd, 0); |
| 1241 sw(scratch, rs); |
| 1242 } |
1231 } | 1243 } |
1232 | 1244 |
1233 | 1245 |
1234 void MacroAssembler::li(Register dst, Handle<Object> value, LiFlags mode) { | 1246 void MacroAssembler::li(Register dst, Handle<Object> value, LiFlags mode) { |
1235 AllowDeferredHandleDereference smi_check; | 1247 AllowDeferredHandleDereference smi_check; |
1236 if (value->IsSmi()) { | 1248 if (value->IsSmi()) { |
1237 li(dst, Operand(value), mode); | 1249 li(dst, Operand(value), mode); |
1238 } else { | 1250 } else { |
1239 DCHECK(value->IsHeapObject()); | 1251 DCHECK(value->IsHeapObject()); |
1240 if (isolate()->heap()->InNewSpace(*value)) { | 1252 if (isolate()->heap()->InNewSpace(*value)) { |
(...skipping 2541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3782 And(scratch, src, kPointerSize - 1); | 3794 And(scratch, src, kPointerSize - 1); |
3783 Assert(eq, kExpectingAlignmentForCopyBytes, | 3795 Assert(eq, kExpectingAlignmentForCopyBytes, |
3784 scratch, Operand(zero_reg)); | 3796 scratch, Operand(zero_reg)); |
3785 } | 3797 } |
3786 Branch(&byte_loop, lt, length, Operand(kPointerSize)); | 3798 Branch(&byte_loop, lt, length, Operand(kPointerSize)); |
3787 ld(scratch, MemOperand(src)); | 3799 ld(scratch, MemOperand(src)); |
3788 Daddu(src, src, kPointerSize); | 3800 Daddu(src, src, kPointerSize); |
3789 | 3801 |
3790 // TODO(kalmard) check if this can be optimized to use sw in most cases. | 3802 // TODO(kalmard) check if this can be optimized to use sw in most cases. |
3791 // Can't use unaligned access - copy byte by byte. | 3803 // Can't use unaligned access - copy byte by byte. |
3792 sb(scratch, MemOperand(dst, 0)); | 3804 if (kArchEndian == kLittle) { |
3793 dsrl(scratch, scratch, 8); | 3805 sb(scratch, MemOperand(dst, 0)); |
3794 sb(scratch, MemOperand(dst, 1)); | 3806 dsrl(scratch, scratch, 8); |
3795 dsrl(scratch, scratch, 8); | 3807 sb(scratch, MemOperand(dst, 1)); |
3796 sb(scratch, MemOperand(dst, 2)); | 3808 dsrl(scratch, scratch, 8); |
3797 dsrl(scratch, scratch, 8); | 3809 sb(scratch, MemOperand(dst, 2)); |
3798 sb(scratch, MemOperand(dst, 3)); | 3810 dsrl(scratch, scratch, 8); |
3799 dsrl(scratch, scratch, 8); | 3811 sb(scratch, MemOperand(dst, 3)); |
3800 sb(scratch, MemOperand(dst, 4)); | 3812 dsrl(scratch, scratch, 8); |
3801 dsrl(scratch, scratch, 8); | 3813 sb(scratch, MemOperand(dst, 4)); |
3802 sb(scratch, MemOperand(dst, 5)); | 3814 dsrl(scratch, scratch, 8); |
3803 dsrl(scratch, scratch, 8); | 3815 sb(scratch, MemOperand(dst, 5)); |
3804 sb(scratch, MemOperand(dst, 6)); | 3816 dsrl(scratch, scratch, 8); |
3805 dsrl(scratch, scratch, 8); | 3817 sb(scratch, MemOperand(dst, 6)); |
3806 sb(scratch, MemOperand(dst, 7)); | 3818 dsrl(scratch, scratch, 8); |
| 3819 sb(scratch, MemOperand(dst, 7)); |
| 3820 } else { |
| 3821 sb(scratch, MemOperand(dst, 7)); |
| 3822 dsrl(scratch, scratch, 8); |
| 3823 sb(scratch, MemOperand(dst, 6)); |
| 3824 dsrl(scratch, scratch, 8); |
| 3825 sb(scratch, MemOperand(dst, 5)); |
| 3826 dsrl(scratch, scratch, 8); |
| 3827 sb(scratch, MemOperand(dst, 4)); |
| 3828 dsrl(scratch, scratch, 8); |
| 3829 sb(scratch, MemOperand(dst, 3)); |
| 3830 dsrl(scratch, scratch, 8); |
| 3831 sb(scratch, MemOperand(dst, 2)); |
| 3832 dsrl(scratch, scratch, 8); |
| 3833 sb(scratch, MemOperand(dst, 1)); |
| 3834 dsrl(scratch, scratch, 8); |
| 3835 sb(scratch, MemOperand(dst, 0)); |
| 3836 } |
3807 Daddu(dst, dst, 8); | 3837 Daddu(dst, dst, 8); |
3808 | 3838 |
3809 Dsubu(length, length, Operand(kPointerSize)); | 3839 Dsubu(length, length, Operand(kPointerSize)); |
3810 Branch(&word_loop); | 3840 Branch(&word_loop); |
3811 | 3841 |
3812 // Copy the last bytes if any left. | 3842 // Copy the last bytes if any left. |
3813 bind(&byte_loop); | 3843 bind(&byte_loop); |
3814 Branch(&done, eq, length, Operand(zero_reg)); | 3844 Branch(&done, eq, length, Operand(zero_reg)); |
3815 bind(&byte_loop_1); | 3845 bind(&byte_loop_1); |
3816 lbu(scratch, MemOperand(src)); | 3846 lbu(scratch, MemOperand(src)); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3994 | 4024 |
3995 void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell, | 4025 void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell, |
3996 Label* miss) { | 4026 Label* miss) { |
3997 GetWeakValue(value, cell); | 4027 GetWeakValue(value, cell); |
3998 JumpIfSmi(value, miss); | 4028 JumpIfSmi(value, miss); |
3999 } | 4029 } |
4000 | 4030 |
4001 | 4031 |
4002 void MacroAssembler::MovFromFloatResult(const DoubleRegister dst) { | 4032 void MacroAssembler::MovFromFloatResult(const DoubleRegister dst) { |
4003 if (IsMipsSoftFloatABI) { | 4033 if (IsMipsSoftFloatABI) { |
4004 Move(dst, v0, v1); | 4034 if (kArchEndian == kLittle) { |
| 4035 Move(dst, v0, v1); |
| 4036 } else { |
| 4037 Move(dst, v1, v0); |
| 4038 } |
4005 } else { | 4039 } else { |
4006 Move(dst, f0); // Reg f0 is o32 ABI FP return value. | 4040 Move(dst, f0); // Reg f0 is o32 ABI FP return value. |
4007 } | 4041 } |
4008 } | 4042 } |
4009 | 4043 |
4010 | 4044 |
4011 void MacroAssembler::MovFromFloatParameter(const DoubleRegister dst) { | 4045 void MacroAssembler::MovFromFloatParameter(const DoubleRegister dst) { |
4012 if (IsMipsSoftFloatABI) { | 4046 if (IsMipsSoftFloatABI) { |
4013 Move(dst, a0, a1); | 4047 if (kArchEndian == kLittle) { |
| 4048 Move(dst, a0, a1); |
| 4049 } else { |
| 4050 Move(dst, a1, a0); |
| 4051 } |
4014 } else { | 4052 } else { |
4015 Move(dst, f12); // Reg f12 is o32 ABI FP first argument value. | 4053 Move(dst, f12); // Reg f12 is n64 ABI FP first argument value. |
4016 } | 4054 } |
4017 } | 4055 } |
4018 | 4056 |
4019 | 4057 |
4020 void MacroAssembler::MovToFloatParameter(DoubleRegister src) { | 4058 void MacroAssembler::MovToFloatParameter(DoubleRegister src) { |
4021 if (!IsMipsSoftFloatABI) { | 4059 if (!IsMipsSoftFloatABI) { |
4022 Move(f12, src); | 4060 Move(f12, src); |
4023 } else { | 4061 } else { |
4024 Move(a0, a1, src); | 4062 if (kArchEndian == kLittle) { |
| 4063 Move(a0, a1, src); |
| 4064 } else { |
| 4065 Move(a1, a0, src); |
| 4066 } |
4025 } | 4067 } |
4026 } | 4068 } |
4027 | 4069 |
4028 | 4070 |
4029 void MacroAssembler::MovToFloatResult(DoubleRegister src) { | 4071 void MacroAssembler::MovToFloatResult(DoubleRegister src) { |
4030 if (!IsMipsSoftFloatABI) { | 4072 if (!IsMipsSoftFloatABI) { |
4031 Move(f0, src); | 4073 Move(f0, src); |
4032 } else { | 4074 } else { |
4033 Move(v0, v1, src); | 4075 if (kArchEndian == kLittle) { |
| 4076 Move(v0, v1, src); |
| 4077 } else { |
| 4078 Move(v1, v0, src); |
| 4079 } |
4034 } | 4080 } |
4035 } | 4081 } |
4036 | 4082 |
4037 | 4083 |
4038 void MacroAssembler::MovToFloatParameters(DoubleRegister src1, | 4084 void MacroAssembler::MovToFloatParameters(DoubleRegister src1, |
4039 DoubleRegister src2) { | 4085 DoubleRegister src2) { |
4040 if (!IsMipsSoftFloatABI) { | 4086 if (!IsMipsSoftFloatABI) { |
4041 const DoubleRegister fparg2 = (kMipsAbi == kN64) ? f13 : f14; | 4087 const DoubleRegister fparg2 = (kMipsAbi == kN64) ? f13 : f14; |
4042 if (src2.is(f12)) { | 4088 if (src2.is(f12)) { |
4043 DCHECK(!src1.is(fparg2)); | 4089 DCHECK(!src1.is(fparg2)); |
4044 Move(fparg2, src2); | 4090 Move(fparg2, src2); |
4045 Move(f12, src1); | 4091 Move(f12, src1); |
4046 } else { | 4092 } else { |
4047 Move(f12, src1); | 4093 Move(f12, src1); |
4048 Move(fparg2, src2); | 4094 Move(fparg2, src2); |
4049 } | 4095 } |
4050 } else { | 4096 } else { |
4051 Move(a0, a1, src1); | 4097 if (kArchEndian == kLittle) { |
4052 Move(a2, a3, src2); | 4098 Move(a0, a1, src1); |
| 4099 Move(a2, a3, src2); |
| 4100 } else { |
| 4101 Move(a1, a0, src1); |
| 4102 Move(a3, a2, src2); |
| 4103 } |
4053 } | 4104 } |
4054 } | 4105 } |
4055 | 4106 |
4056 | 4107 |
4057 // ----------------------------------------------------------------------------- | 4108 // ----------------------------------------------------------------------------- |
4058 // JavaScript invokes. | 4109 // JavaScript invokes. |
4059 | 4110 |
4060 void MacroAssembler::InvokePrologue(const ParameterCount& expected, | 4111 void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
4061 const ParameterCount& actual, | 4112 const ParameterCount& actual, |
4062 Handle<Code> code_constant, | 4113 Handle<Code> code_constant, |
(...skipping 2144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6207 if (mag.shift > 0) sra(result, result, mag.shift); | 6258 if (mag.shift > 0) sra(result, result, mag.shift); |
6208 srl(at, dividend, 31); | 6259 srl(at, dividend, 31); |
6209 Addu(result, result, Operand(at)); | 6260 Addu(result, result, Operand(at)); |
6210 } | 6261 } |
6211 | 6262 |
6212 | 6263 |
6213 } // namespace internal | 6264 } // namespace internal |
6214 } // namespace v8 | 6265 } // namespace v8 |
6215 | 6266 |
6216 #endif // V8_TARGET_ARCH_MIPS64 | 6267 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |