| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 <stdarg.h> | 5 #include <stdarg.h> |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #if V8_TARGET_ARCH_PPC | 9 #if V8_TARGET_ARCH_PPC |
| 10 | 10 |
| (...skipping 2898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2909 return; | 2909 return; |
| 2910 } | 2910 } |
| 2911 case FCTID: { | 2911 case FCTID: { |
| 2912 int frt = instr->RTValue(); | 2912 int frt = instr->RTValue(); |
| 2913 int frb = instr->RBValue(); | 2913 int frb = instr->RBValue(); |
| 2914 double frb_val = get_double_from_d_register(frb); | 2914 double frb_val = get_double_from_d_register(frb); |
| 2915 int64_t frt_val; | 2915 int64_t frt_val; |
| 2916 int64_t one = 1; // work-around gcc | 2916 int64_t one = 1; // work-around gcc |
| 2917 int64_t kMinLongLong = (one << 63); | 2917 int64_t kMinLongLong = (one << 63); |
| 2918 int64_t kMaxLongLong = kMinLongLong - 1; | 2918 int64_t kMaxLongLong = kMinLongLong - 1; |
| 2919 bool invalid_convert = false; |
| 2919 | 2920 |
| 2920 if (frb_val > kMaxLongLong) { | 2921 if (std::isnan(frb_val) || frb_val < kMinLongLong) { |
| 2922 frt_val = kMinLongLong; |
| 2923 invalid_convert = true; |
| 2924 } else if (frb_val > kMaxLongLong) { |
| 2921 frt_val = kMaxLongLong; | 2925 frt_val = kMaxLongLong; |
| 2922 } else if (frb_val < kMinLongLong) { | 2926 invalid_convert = true; |
| 2923 frt_val = kMinLongLong; | |
| 2924 } else { | 2927 } else { |
| 2925 switch (fp_condition_reg_ & kFPRoundingModeMask) { | 2928 switch (fp_condition_reg_ & kFPRoundingModeMask) { |
| 2926 case kRoundToZero: | 2929 case kRoundToZero: |
| 2927 frt_val = (int64_t)frb_val; | 2930 frt_val = (int64_t)frb_val; |
| 2928 break; | 2931 break; |
| 2929 case kRoundToPlusInf: | 2932 case kRoundToPlusInf: |
| 2930 frt_val = (int64_t)std::ceil(frb_val); | 2933 frt_val = (int64_t)std::ceil(frb_val); |
| 2931 break; | 2934 break; |
| 2932 case kRoundToMinusInf: | 2935 case kRoundToMinusInf: |
| 2933 frt_val = (int64_t)std::floor(frb_val); | 2936 frt_val = (int64_t)std::floor(frb_val); |
| 2934 break; | 2937 break; |
| 2935 default: | 2938 default: |
| 2936 frt_val = (int64_t)frb_val; | 2939 frt_val = (int64_t)frb_val; |
| 2937 UNIMPLEMENTED(); // Not used by V8. | 2940 UNIMPLEMENTED(); // Not used by V8. |
| 2938 break; | 2941 break; |
| 2939 } | 2942 } |
| 2940 } | 2943 } |
| 2941 set_d_register(frt, frt_val); | 2944 set_d_register(frt, frt_val); |
| 2945 if (invalid_convert) SetFPSCR(VXCVI); |
| 2942 return; | 2946 return; |
| 2943 } | 2947 } |
| 2944 case FCTIDZ: { | 2948 case FCTIDZ: { |
| 2945 int frt = instr->RTValue(); | 2949 int frt = instr->RTValue(); |
| 2946 int frb = instr->RBValue(); | 2950 int frb = instr->RBValue(); |
| 2947 double frb_val = get_double_from_d_register(frb); | 2951 double frb_val = get_double_from_d_register(frb); |
| 2948 int64_t frt_val; | 2952 int64_t frt_val; |
| 2949 int64_t one = 1; // work-around gcc | 2953 int64_t one = 1; // work-around gcc |
| 2950 int64_t kMinLongLong = (one << 63); | 2954 int64_t kMinLongLong = (one << 63); |
| 2951 int64_t kMaxLongLong = kMinLongLong - 1; | 2955 int64_t kMaxLongLong = kMinLongLong - 1; |
| 2956 bool invalid_convert = false; |
| 2952 | 2957 |
| 2953 if (frb_val > kMaxLongLong) { | 2958 if (std::isnan(frb_val) || frb_val < kMinLongLong) { |
| 2959 frt_val = kMinLongLong; |
| 2960 invalid_convert = true; |
| 2961 } else if (frb_val > kMaxLongLong) { |
| 2954 frt_val = kMaxLongLong; | 2962 frt_val = kMaxLongLong; |
| 2955 } else if (frb_val < kMinLongLong) { | 2963 invalid_convert = true; |
| 2956 frt_val = kMinLongLong; | |
| 2957 } else { | 2964 } else { |
| 2958 frt_val = (int64_t)frb_val; | 2965 frt_val = (int64_t)frb_val; |
| 2959 } | 2966 } |
| 2960 set_d_register(frt, frt_val); | 2967 set_d_register(frt, frt_val); |
| 2968 if (invalid_convert) SetFPSCR(VXCVI); |
| 2961 return; | 2969 return; |
| 2962 } | 2970 } |
| 2963 case FCTIDU: { | 2971 case FCTIDU: { |
| 2964 int frt = instr->RTValue(); | 2972 int frt = instr->RTValue(); |
| 2965 int frb = instr->RBValue(); | 2973 int frb = instr->RBValue(); |
| 2966 double frb_val = get_double_from_d_register(frb); | 2974 double frb_val = get_double_from_d_register(frb); |
| 2967 uint64_t frt_val; | 2975 uint64_t frt_val; |
| 2968 uint64_t kMinLongLong = 0; | 2976 uint64_t kMinLongLong = 0; |
| 2969 uint64_t kMaxLongLong = kMinLongLong - 1; | 2977 uint64_t kMaxLongLong = kMinLongLong - 1; |
| 2978 bool invalid_convert = false; |
| 2970 | 2979 |
| 2971 if (frb_val > kMaxLongLong) { | 2980 if (std::isnan(frb_val) || frb_val < kMinLongLong) { |
| 2981 frt_val = kMinLongLong; |
| 2982 invalid_convert = true; |
| 2983 } else if (frb_val > kMaxLongLong) { |
| 2972 frt_val = kMaxLongLong; | 2984 frt_val = kMaxLongLong; |
| 2973 } else if (frb_val < kMinLongLong) { | 2985 invalid_convert = true; |
| 2974 frt_val = kMinLongLong; | |
| 2975 } else { | 2986 } else { |
| 2976 switch (fp_condition_reg_ & kFPRoundingModeMask) { | 2987 switch (fp_condition_reg_ & kFPRoundingModeMask) { |
| 2977 case kRoundToZero: | 2988 case kRoundToZero: |
| 2978 frt_val = (uint64_t)frb_val; | 2989 frt_val = (uint64_t)frb_val; |
| 2979 break; | 2990 break; |
| 2980 case kRoundToPlusInf: | 2991 case kRoundToPlusInf: |
| 2981 frt_val = (uint64_t)std::ceil(frb_val); | 2992 frt_val = (uint64_t)std::ceil(frb_val); |
| 2982 break; | 2993 break; |
| 2983 case kRoundToMinusInf: | 2994 case kRoundToMinusInf: |
| 2984 frt_val = (uint64_t)std::floor(frb_val); | 2995 frt_val = (uint64_t)std::floor(frb_val); |
| 2985 break; | 2996 break; |
| 2986 default: | 2997 default: |
| 2987 frt_val = (uint64_t)frb_val; | 2998 frt_val = (uint64_t)frb_val; |
| 2988 UNIMPLEMENTED(); // Not used by V8. | 2999 UNIMPLEMENTED(); // Not used by V8. |
| 2989 break; | 3000 break; |
| 2990 } | 3001 } |
| 2991 } | 3002 } |
| 2992 set_d_register(frt, frt_val); | 3003 set_d_register(frt, frt_val); |
| 3004 if (invalid_convert) SetFPSCR(VXCVI); |
| 2993 return; | 3005 return; |
| 2994 } | 3006 } |
| 2995 case FCTIDUZ: { | 3007 case FCTIDUZ: { |
| 2996 int frt = instr->RTValue(); | 3008 int frt = instr->RTValue(); |
| 2997 int frb = instr->RBValue(); | 3009 int frb = instr->RBValue(); |
| 2998 double frb_val = get_double_from_d_register(frb); | 3010 double frb_val = get_double_from_d_register(frb); |
| 2999 uint64_t frt_val; | 3011 uint64_t frt_val; |
| 3000 uint64_t kMinLongLong = 0; | 3012 uint64_t kMinLongLong = 0; |
| 3001 uint64_t kMaxLongLong = kMinLongLong - 1; | 3013 uint64_t kMaxLongLong = kMinLongLong - 1; |
| 3014 bool invalid_convert = false; |
| 3002 | 3015 |
| 3003 if (frb_val > kMaxLongLong) { | 3016 if (std::isnan(frb_val) || frb_val < kMinLongLong) { |
| 3017 frt_val = kMinLongLong; |
| 3018 invalid_convert = true; |
| 3019 } else if (frb_val > kMaxLongLong) { |
| 3004 frt_val = kMaxLongLong; | 3020 frt_val = kMaxLongLong; |
| 3005 } else if (frb_val < kMinLongLong) { | 3021 invalid_convert = true; |
| 3006 frt_val = kMinLongLong; | |
| 3007 } else { | 3022 } else { |
| 3008 frt_val = (uint64_t)frb_val; | 3023 frt_val = (uint64_t)frb_val; |
| 3009 } | 3024 } |
| 3010 set_d_register(frt, frt_val); | 3025 set_d_register(frt, frt_val); |
| 3026 if (invalid_convert) SetFPSCR(VXCVI); |
| 3011 return; | 3027 return; |
| 3012 } | 3028 } |
| 3013 case FCTIW: | 3029 case FCTIW: |
| 3014 case FCTIWZ: { | 3030 case FCTIWZ: { |
| 3015 int frt = instr->RTValue(); | 3031 int frt = instr->RTValue(); |
| 3016 int frb = instr->RBValue(); | 3032 int frb = instr->RBValue(); |
| 3017 double frb_val = get_double_from_d_register(frb); | 3033 double frb_val = get_double_from_d_register(frb); |
| 3018 int64_t frt_val; | 3034 int64_t frt_val; |
| 3019 if (frb_val > kMaxInt) { | 3035 if (frb_val > kMaxInt) { |
| 3020 frt_val = kMaxInt; | 3036 frt_val = kMaxInt; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3097 // int flm = instr->Bits(24, 17); | 3113 // int flm = instr->Bits(24, 17); |
| 3098 } | 3114 } |
| 3099 return; | 3115 return; |
| 3100 } | 3116 } |
| 3101 case MFFS: { | 3117 case MFFS: { |
| 3102 int frt = instr->RTValue(); | 3118 int frt = instr->RTValue(); |
| 3103 int64_t lval = static_cast<int64_t>(fp_condition_reg_); | 3119 int64_t lval = static_cast<int64_t>(fp_condition_reg_); |
| 3104 set_d_register(frt, lval); | 3120 set_d_register(frt, lval); |
| 3105 return; | 3121 return; |
| 3106 } | 3122 } |
| 3123 case MCRFS: { |
| 3124 int bf = instr->Bits(25, 23); |
| 3125 int bfa = instr->Bits(20, 18); |
| 3126 int cr_shift = (7 - bf) * CRWIDTH; |
| 3127 int fp_shift = (7 - bfa) * CRWIDTH; |
| 3128 int field_val = (fp_condition_reg_ >> fp_shift) & 0xf; |
| 3129 condition_reg_ &= ~(0x0f << cr_shift); |
| 3130 condition_reg_ |= (field_val << cr_shift); |
| 3131 // Clear copied exception bits |
| 3132 switch (bfa) { |
| 3133 case 5: |
| 3134 ClearFPSCR(VXSOFT); |
| 3135 ClearFPSCR(VXSQRT); |
| 3136 ClearFPSCR(VXCVI); |
| 3137 break; |
| 3138 default: |
| 3139 UNIMPLEMENTED(); |
| 3140 break; |
| 3141 } |
| 3142 return; |
| 3143 } |
| 3144 case MTFSB0: { |
| 3145 int bt = instr->Bits(25, 21); |
| 3146 ClearFPSCR(bt); |
| 3147 if (instr->Bit(0)) { // RC bit set |
| 3148 UNIMPLEMENTED(); |
| 3149 } |
| 3150 return; |
| 3151 } |
| 3152 case MTFSB1: { |
| 3153 int bt = instr->Bits(25, 21); |
| 3154 SetFPSCR(bt); |
| 3155 if (instr->Bit(0)) { // RC bit set |
| 3156 UNIMPLEMENTED(); |
| 3157 } |
| 3158 return; |
| 3159 } |
| 3107 case FABS: { | 3160 case FABS: { |
| 3108 int frt = instr->RTValue(); | 3161 int frt = instr->RTValue(); |
| 3109 int frb = instr->RBValue(); | 3162 int frb = instr->RBValue(); |
| 3110 double frb_val = get_double_from_d_register(frb); | 3163 double frb_val = get_double_from_d_register(frb); |
| 3111 double frt_val = std::fabs(frb_val); | 3164 double frt_val = std::fabs(frb_val); |
| 3112 set_d_register_from_double(frt, frt_val); | 3165 set_d_register_from_double(frt, frt_val); |
| 3113 return; | 3166 return; |
| 3114 } | 3167 } |
| 3115 } | 3168 } |
| 3116 UNIMPLEMENTED(); // Not used by V8. | 3169 UNIMPLEMENTED(); // Not used by V8. |
| (...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4008 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); | 4061 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); |
| 4009 uintptr_t address = *stack_slot; | 4062 uintptr_t address = *stack_slot; |
| 4010 set_register(sp, current_sp + sizeof(uintptr_t)); | 4063 set_register(sp, current_sp + sizeof(uintptr_t)); |
| 4011 return address; | 4064 return address; |
| 4012 } | 4065 } |
| 4013 } // namespace internal | 4066 } // namespace internal |
| 4014 } // namespace v8 | 4067 } // namespace v8 |
| 4015 | 4068 |
| 4016 #endif // USE_SIMULATOR | 4069 #endif // USE_SIMULATOR |
| 4017 #endif // V8_TARGET_ARCH_PPC | 4070 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |