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 |