Changeset 224623 in webkit
- Timestamp:
- Nov 9, 2017 1:02:10 AM (6 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r224607 r224623 1 2017-11-09 Guillaume Emont <guijemont@igalia.com> 2 3 [JSC][MIPS] Use fcsr to check the validity of the result of trunc.w.d 4 https://bugs.webkit.org/show_bug.cgi?id=179446 5 6 Reviewed by Žan Doberšek. 7 8 The trunc.w.d mips instruction should give a 0x7fffffff result when 9 the source value is Infinity, NaN, or rounds to an integer outside the 10 range -2^31 to 2^31 -1. This is what branchTruncateDoubleToInt32() and 11 branchTruncateDoubleToUInt32() have been relying on. It turns out that 12 this assumption is not true on some CPUs, including on the ci20 on 13 which we run the testbot (we get 0x80000000 instead). We should the 14 invalid operation cause bit instead to check whether the source value 15 could be properly truncated. This requires the addition of the cfc1 16 instruction, as well as the special registers that can be used with it 17 (control registers of CP1). 18 19 * assembler/MIPSAssembler.h: 20 (JSC::MIPSAssembler::firstSPRegister): 21 (JSC::MIPSAssembler::lastSPRegister): 22 (JSC::MIPSAssembler::numberOfSPRegisters): 23 (JSC::MIPSAssembler::sprName): 24 Added control registers of CP1. 25 (JSC::MIPSAssembler::cfc1): 26 Added. 27 * assembler/MacroAssemblerMIPS.h: 28 (JSC::MacroAssemblerMIPS::branchOnTruncateResult): 29 (JSC::MacroAssemblerMIPS::branchTruncateDoubleToInt32): 30 (JSC::MacroAssemblerMIPS::branchTruncateDoubleToUint32): 31 Use fcsr to check if the value could be properly truncated. 32 1 33 2017-11-08 Jeremy Jones <jeremyj@apple.com> 2 34 -
trunk/Source/JavaScriptCore/assembler/MIPSAssembler.h
r224258 r224623 109 109 } RegisterID; 110 110 111 // Currently, we don't have support for any special purpose registers.112 111 typedef enum { 113 firstInvalidSPR, 114 lastInvalidSPR = -1, 112 fir = 0, 113 fccr = 25, 114 fexr = 26, 115 fenr = 28, 116 fcsr = 31 115 117 } SPRegisterID; 116 118 … … 163 165 static constexpr unsigned numberOfRegisters() { return lastRegister() - firstRegister() + 1; } 164 166 165 static constexpr SPRegisterID firstSPRegister() { return MIPSRegisters::fir stInvalidSPR; }166 static constexpr SPRegisterID lastSPRegister() { return MIPSRegisters:: lastInvalidSPR; }167 static constexpr unsigned numberOfSPRegisters() { return 0; }167 static constexpr SPRegisterID firstSPRegister() { return MIPSRegisters::fir; } 168 static constexpr SPRegisterID lastSPRegister() { return MIPSRegisters::fcsr; } 169 static constexpr unsigned numberOfSPRegisters() { return 5; } 168 170 169 171 static constexpr FPRegisterID firstFPRegister() { return MIPSRegisters::f0; } … … 185 187 static const char* sprName(SPRegisterID id) 186 188 { 187 // Currently, we don't have support for any special purpose registers. 188 RELEASE_ASSERT_NOT_REACHED(); 189 switch (id) { 190 case MIPSRegisters::fir: 191 return "fir"; 192 case MIPSRegisters::fccr: 193 return "fccr"; 194 case MIPSRegisters::fexr: 195 return "fexr"; 196 case MIPSRegisters::fenr: 197 return "fenr"; 198 case MIPSRegisters::fcsr: 199 return "fcsr"; 200 default: 201 RELEASE_ASSERT_NOT_REACHED(); 202 } 189 203 } 190 204 … … 225 239 }; 226 240 241 // FCSR Bits 242 enum { 243 FP_CAUSE_INVALID_OPERATION = 1 << 16 244 }; 245 227 246 void emitInst(MIPSWord op) 228 247 { … … 715 734 { 716 735 emitInst(0x46200035 | (fs << OP_SH_FS) | (ft << OP_SH_FT)); 736 copDelayNop(); 737 } 738 739 void cfc1(RegisterID rt, SPRegisterID fs) 740 { 741 emitInst(0x44400000 | (rt << OP_SH_RT) | (fs << OP_SH_FS)); 717 742 copDelayNop(); 718 743 } -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
r223916 r224623 2953 2953 // Truncates 'src' to an integer, and places the resulting 'dest'. 2954 2954 // If the result is not representable as a 32 bit value, branch. 2955 // May also branch for some values that are representable in 32 bits2956 // (specifically, in this case, INT_MAX 0x7fffffff).2957 2955 enum BranchTruncateType { BranchIfTruncateFailed, BranchIfTruncateSuccessful }; 2956 2957 Jump branchOnTruncateResult(BranchTruncateType branchType) 2958 { 2959 m_assembler.cfc1(dataTempRegister, MIPSRegisters::fcsr); 2960 and32(TrustedImm32(MIPSAssembler::FP_CAUSE_INVALID_OPERATION), dataTempRegister); 2961 return branch32(branchType == BranchIfTruncateFailed ? NotEqual : Equal, dataTempRegister, MIPSRegisters::zero); 2962 } 2963 2958 2964 Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed) 2959 2965 { 2960 2966 m_assembler.truncwd(fpTempRegister, src); 2967 Jump truncateResult = branchOnTruncateResult(branchType); 2961 2968 m_assembler.mfc1(dest, fpTempRegister); 2962 return branch32(branchType == BranchIfTruncateFailed ? Equal : NotEqual, dest, TrustedImm32(0x7fffffff));2969 return truncateResult; 2963 2970 } 2964 2971 … … 2966 2973 { 2967 2974 m_assembler.truncwd(fpTempRegister, src); 2975 Jump truncateResult = branchOnTruncateResult(branchType); 2968 2976 m_assembler.mfc1(dest, fpTempRegister); 2969 return branch32(branchType == BranchIfTruncateFailed ? Equal : NotEqual, dest, TrustedImm32(0x7fffffff));2977 return truncateResult; 2970 2978 } 2971 2979
Note: See TracChangeset
for help on using the changeset viewer.