Index: src/mips/macro-assembler-mips.cc |
=================================================================== |
--- src/mips/macro-assembler-mips.cc (revision 9004) |
+++ src/mips/macro-assembler-mips.cc (working copy) |
@@ -757,15 +757,22 @@ |
uint16_t pos, |
uint16_t size) { |
ASSERT(pos < 32); |
- ASSERT(pos + size < 32); |
+ ASSERT(pos + size < 33); |
if (mips32r2) { |
ext_(rt, rs, pos, size); |
} else { |
// Move rs to rt and shift it left then right to get the |
// desired bitfield on the right side and zeroes on the left. |
- sll(rt, rs, 32 - (pos + size)); |
- srl(rt, rt, 32 - size); |
+ int shift_left = 32 - (pos + size); |
+ if (shift_left > 0) { |
+ sll(rt, rs, shift_left); |
+ } |
+ |
+ int shift_right = 32 - size; |
+ if (shift_right > 0) { |
+ srl(rt, rt, shift_right); |
+ } |
} |
} |
@@ -807,28 +814,32 @@ |
} |
-void MacroAssembler::Cvt_d_uw(FPURegister fd, FPURegister fs) { |
- // Move the data from fs to t4. |
- mfc1(t4, fs); |
- return Cvt_d_uw(fd, t4); |
+void MacroAssembler::Cvt_d_uw(FPURegister fd, |
+ FPURegister fs, |
+ FPURegister scratch) { |
+ // Move the data from fs to t8. |
+ mfc1(t8, fs); |
+ Cvt_d_uw(fd, t8, scratch); |
} |
-void MacroAssembler::Cvt_d_uw(FPURegister fd, Register rs) { |
+void MacroAssembler::Cvt_d_uw(FPURegister fd, |
+ Register rs, |
+ FPURegister scratch) { |
// Convert rs to a FP value in fd (and fd + 1). |
// We do this by converting rs minus the MSB to avoid sign conversion, |
- // then adding 2^31-1 and 1 to the result. |
+ // then adding 2^31 to the result (if needed). |
- ASSERT(!fd.is(f20)); |
+ ASSERT(!fd.is(scratch)); |
ASSERT(!rs.is(t9)); |
- ASSERT(!rs.is(t8)); |
+ ASSERT(!rs.is(at)); |
- // Save rs's MSB to t8. |
- And(t8, rs, 0x80000000); |
+ // Save rs's MSB to t9. |
+ Ext(t9, rs, 31, 1); |
// Remove rs's MSB. |
- And(t9, rs, 0x7FFFFFFF); |
- // Move t9 to fd. |
- mtc1(t9, fd); |
+ Ext(at, rs, 0, 31); |
+ // Move the result to fd. |
+ mtc1(at, fd); |
// Convert fd to a real FP value. |
cvt_d_w(fd, fd); |
@@ -837,60 +848,57 @@ |
// If rs's MSB was 0, it's done. |
// Otherwise we need to add that to the FP register. |
- Branch(&conversion_done, eq, t8, Operand(zero_reg)); |
+ Branch(&conversion_done, eq, t9, Operand(zero_reg)); |
- // First load 2^31 - 1 into f20. |
- Or(t9, zero_reg, 0x7FFFFFFF); |
- mtc1(t9, f20); |
+ // Load 2^31 into f20 as its float representation. |
+ li(at, 0x41E00000); |
+ mtc1(at, FPURegister::from_code(scratch.code() + 1)); |
+ mtc1(zero_reg, scratch); |
+ // Add it to fd. |
+ add_d(fd, fd, scratch); |
- // Convert it to FP and add it to fd. |
- cvt_d_w(f20, f20); |
- add_d(fd, fd, f20); |
- // Now add 1. |
- Or(t9, zero_reg, 1); |
- mtc1(t9, f20); |
- |
- cvt_d_w(f20, f20); |
- add_d(fd, fd, f20); |
bind(&conversion_done); |
} |
-void MacroAssembler::Trunc_uw_d(FPURegister fd, FPURegister fs) { |
- Trunc_uw_d(fs, t4); |
- mtc1(t4, fd); |
+void MacroAssembler::Trunc_uw_d(FPURegister fd, |
+ FPURegister fs, |
+ FPURegister scratch) { |
+ Trunc_uw_d(fs, t8, scratch); |
+ mtc1(t8, fd); |
} |
-void MacroAssembler::Trunc_uw_d(FPURegister fd, Register rs) { |
- ASSERT(!fd.is(f22)); |
- ASSERT(!rs.is(t8)); |
+void MacroAssembler::Trunc_uw_d(FPURegister fd, |
+ Register rs, |
+ FPURegister scratch) { |
+ ASSERT(!fd.is(scratch)); |
+ ASSERT(!rs.is(at)); |
- // Load 2^31 into f22. |
- Or(t8, zero_reg, 0x80000000); |
- Cvt_d_uw(f22, t8); |
+ // Load 2^31 into scratch as its float representation. |
+ li(at, 0x41E00000); |
+ mtc1(at, FPURegister::from_code(scratch.code() + 1)); |
+ mtc1(zero_reg, scratch); |
+ // Test if scratch > fd. |
+ c(OLT, D, fd, scratch); |
- // Test if f22 > fd. |
- c(OLT, D, fd, f22); |
- |
Label simple_convert; |
// If fd < 2^31 we can convert it normally. |
bc1t(&simple_convert); |
// First we subtract 2^31 from fd, then trunc it to rs |
// and add 2^31 to rs. |
+ sub_d(scratch, fd, scratch); |
+ trunc_w_d(scratch, scratch); |
+ mfc1(rs, scratch); |
+ Or(rs, rs, 1 << 31); |
- sub_d(f22, fd, f22); |
- trunc_w_d(f22, f22); |
- mfc1(rs, f22); |
- or_(rs, rs, t8); |
- |
Label done; |
Branch(&done); |
// Simple conversion. |
bind(&simple_convert); |
- trunc_w_d(f22, fd); |
- mfc1(rs, f22); |
+ trunc_w_d(scratch, fd); |
+ mfc1(rs, scratch); |
bind(&done); |
} |