Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(322)

Side by Side Diff: test/cctest/test-macro-assembler-mips64.cc

Issue 2534413002: MIPS: Improve Float(32|64)(Max|Min). (Closed)
Patch Set: MIPS: Improve Float(32|64)(Max|Min). Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/cctest/test-macro-assembler-mips.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 24 matching lines...) Expand all
35 #include "src/macro-assembler.h" 35 #include "src/macro-assembler.h"
36 #include "src/mips64/macro-assembler-mips64.h" 36 #include "src/mips64/macro-assembler-mips64.h"
37 #include "src/mips64/simulator-mips64.h" 37 #include "src/mips64/simulator-mips64.h"
38 38
39 39
40 using namespace v8::internal; 40 using namespace v8::internal;
41 41
42 typedef void* (*F)(int64_t x, int64_t y, int p2, int p3, int p4); 42 typedef void* (*F)(int64_t x, int64_t y, int p2, int p3, int p4);
43 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); 43 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
44 typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); 44 typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
45 typedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4);
45 46
46 #define __ masm-> 47 #define __ masm->
47 48
48 TEST(BYTESWAP) { 49 TEST(BYTESWAP) {
49 DCHECK(kArchVariant == kMips64r6 || kArchVariant == kMips64r2); 50 DCHECK(kArchVariant == kMips64r6 || kArchVariant == kMips64r2);
50 CcTest::InitializeVM(); 51 CcTest::InitializeVM();
51 Isolate* isolate = CcTest::i_isolate(); 52 Isolate* isolate = CcTest::i_isolate();
52 HandleScope scope(isolate); 53 HandleScope scope(isolate);
53 54
54 struct T { 55 struct T {
(...skipping 1451 matching lines...) Expand 10 before | Expand all | Expand 10 after
1506 1507
1507 Label handle_mind_nan, handle_maxd_nan, handle_mins_nan, handle_maxs_nan; 1508 Label handle_mind_nan, handle_maxd_nan, handle_mins_nan, handle_maxs_nan;
1508 Label back_mind_nan, back_maxd_nan, back_mins_nan, back_maxs_nan; 1509 Label back_mind_nan, back_maxd_nan, back_mins_nan, back_maxs_nan;
1509 1510
1510 __ push(s6); 1511 __ push(s6);
1511 __ InitializeRootRegister(); 1512 __ InitializeRootRegister();
1512 __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a))); 1513 __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
1513 __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b))); 1514 __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
1514 __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, e))); 1515 __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, e)));
1515 __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, f))); 1516 __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, f)));
1516 __ MinNaNCheck_d(f10, f4, f8, &handle_mind_nan); 1517 __ Float64Min(f10, f4, f8, &handle_mind_nan);
1517 __ bind(&back_mind_nan); 1518 __ bind(&back_mind_nan);
1518 __ MaxNaNCheck_d(f12, f4, f8, &handle_maxd_nan); 1519 __ Float64Max(f12, f4, f8, &handle_maxd_nan);
1519 __ bind(&back_maxd_nan); 1520 __ bind(&back_maxd_nan);
1520 __ MinNaNCheck_s(f14, f2, f6, &handle_mins_nan); 1521 __ Float32Min(f14, f2, f6, &handle_mins_nan);
1521 __ bind(&back_mins_nan); 1522 __ bind(&back_mins_nan);
1522 __ MaxNaNCheck_s(f16, f2, f6, &handle_maxs_nan); 1523 __ Float32Max(f16, f2, f6, &handle_maxs_nan);
1523 __ bind(&back_maxs_nan); 1524 __ bind(&back_maxs_nan);
1524 __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c))); 1525 __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c)));
1525 __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, d))); 1526 __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, d)));
1526 __ swc1(f14, MemOperand(a0, offsetof(TestFloat, g))); 1527 __ swc1(f14, MemOperand(a0, offsetof(TestFloat, g)));
1527 __ swc1(f16, MemOperand(a0, offsetof(TestFloat, h))); 1528 __ swc1(f16, MemOperand(a0, offsetof(TestFloat, h)));
1528 __ pop(s6); 1529 __ pop(s6);
1529 __ jr(ra); 1530 __ jr(ra);
1530 __ nop(); 1531 __ nop();
1531 1532
1532 handle_dnan(f10, &handle_mind_nan, &back_mind_nan); 1533 handle_dnan(f10, &handle_mind_nan, &back_mind_nan);
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
1960 CHECK_EQ(rs < rd, run_Sltu(rs, rd, fn_1)); 1961 CHECK_EQ(rs < rd, run_Sltu(rs, rd, fn_1));
1961 1962
1962 auto fn_2 = [](MacroAssembler* masm, uint64_t imm) { 1963 auto fn_2 = [](MacroAssembler* masm, uint64_t imm) {
1963 __ Sltu(v0, a0, a1); 1964 __ Sltu(v0, a0, a1);
1964 }; 1965 };
1965 CHECK_EQ(rs < rd, run_Sltu(rs, rd, fn_2)); 1966 CHECK_EQ(rs < rd, run_Sltu(rs, rd, fn_2));
1966 } 1967 }
1967 } 1968 }
1968 } 1969 }
1969 1970
1971 template <typename T, typename Inputs, typename Results>
1972 static ::F4 GenerateMacroFloat32MinMax(MacroAssembler* masm) {
1973 T a = T::from_code(4); // f4
1974 T b = T::from_code(6); // f6
1975 T c = T::from_code(8); // f8
1976
1977 Label ool_min_abc, ool_min_aab, ool_min_aba;
1978 Label ool_max_abc, ool_max_aab, ool_max_aba;
1979
1980 Label done_min_abc, done_min_aab, done_min_aba;
1981 Label done_max_abc, done_max_aab, done_max_aba;
1982
1983 #define FLOAT_MIN_MAX(fminmax, res, x, y, done, ool, res_field) \
1984 __ lwc1(x, MemOperand(a0, offsetof(Inputs, src1_))); \
1985 __ lwc1(y, MemOperand(a0, offsetof(Inputs, src2_))); \
1986 __ fminmax(res, x, y, &ool); \
1987 __ bind(&done); \
1988 __ swc1(a, MemOperand(a1, offsetof(Results, res_field)))
1989
1990 // a = min(b, c);
1991 FLOAT_MIN_MAX(Float32Min, a, b, c, done_min_abc, ool_min_abc, min_abc_);
1992 // a = min(a, b);
1993 FLOAT_MIN_MAX(Float32Min, a, a, b, done_min_aab, ool_min_aab, min_aab_);
1994 // a = min(b, a);
1995 FLOAT_MIN_MAX(Float32Min, a, b, a, done_min_aba, ool_min_aba, min_aba_);
1996
1997 // a = max(b, c);
1998 FLOAT_MIN_MAX(Float32Max, a, b, c, done_max_abc, ool_max_abc, max_abc_);
1999 // a = max(a, b);
2000 FLOAT_MIN_MAX(Float32Max, a, a, b, done_max_aab, ool_max_aab, max_aab_);
2001 // a = max(b, a);
2002 FLOAT_MIN_MAX(Float32Max, a, b, a, done_max_aba, ool_max_aba, max_aba_);
2003
2004 #undef FLOAT_MIN_MAX
2005
2006 __ jr(ra);
2007 __ nop();
2008
2009 // Generate out-of-line cases.
2010 __ bind(&ool_min_abc);
2011 __ Float32MinOutOfLine(a, b, c);
2012 __ b(&done_min_abc);
2013
2014 __ bind(&ool_min_aab);
2015 __ Float32MinOutOfLine(a, a, b);
2016 __ b(&done_min_aab);
2017
2018 __ bind(&ool_min_aba);
2019 __ Float32MinOutOfLine(a, b, a);
2020 __ b(&done_min_aba);
2021
2022 __ bind(&ool_max_abc);
2023 __ Float32MaxOutOfLine(a, b, c);
2024 __ b(&done_max_abc);
2025
2026 __ bind(&ool_max_aab);
2027 __ Float32MaxOutOfLine(a, a, b);
2028 __ b(&done_max_aab);
2029
2030 __ bind(&ool_max_aba);
2031 __ Float32MaxOutOfLine(a, b, a);
2032 __ b(&done_max_aba);
2033
2034 CodeDesc desc;
2035 masm->GetCode(&desc);
2036 Handle<Code> code = masm->isolate()->factory()->NewCode(
2037 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
2038 #ifdef DEBUG
2039 OFStream os(stdout);
2040 code->Print(os);
2041 #endif
2042 return FUNCTION_CAST<::F4>(code->entry());
2043 }
2044
2045 TEST(macro_float_minmax_f32) {
2046 // Test the Float32Min and Float32Max macros.
2047 CcTest::InitializeVM();
2048 Isolate* isolate = CcTest::i_isolate();
2049 HandleScope scope(isolate);
2050
2051 MacroAssembler assembler(isolate, NULL, 0,
2052 v8::internal::CodeObjectRequired::kYes);
2053 MacroAssembler* masm = &assembler;
2054
2055 struct Inputs {
2056 float src1_;
2057 float src2_;
2058 };
2059
2060 struct Results {
2061 // Check all register aliasing possibilities in order to exercise all
2062 // code-paths in the macro assembler.
2063 float min_abc_;
2064 float min_aab_;
2065 float min_aba_;
2066 float max_abc_;
2067 float max_aab_;
2068 float max_aba_;
2069 };
2070
2071 ::F4 f = GenerateMacroFloat32MinMax<FPURegister, Inputs, Results>(masm);
2072 Object* dummy = nullptr;
2073 USE(dummy);
2074
2075 #define CHECK_MINMAX(src1, src2, min, max) \
2076 do { \
2077 Inputs inputs = {src1, src2}; \
2078 Results results; \
2079 dummy = CALL_GENERATED_CODE(isolate, f, &inputs, &results, 0, 0, 0); \
2080 CHECK_EQ(bit_cast<uint32_t>(min), bit_cast<uint32_t>(results.min_abc_)); \
2081 CHECK_EQ(bit_cast<uint32_t>(min), bit_cast<uint32_t>(results.min_aab_)); \
2082 CHECK_EQ(bit_cast<uint32_t>(min), bit_cast<uint32_t>(results.min_aba_)); \
2083 CHECK_EQ(bit_cast<uint32_t>(max), bit_cast<uint32_t>(results.max_abc_)); \
2084 CHECK_EQ(bit_cast<uint32_t>(max), bit_cast<uint32_t>(results.max_aab_)); \
2085 CHECK_EQ(bit_cast<uint32_t>(max), bit_cast<uint32_t>(results.max_aba_)); \
2086 /* Use a bit_cast to correctly identify -0.0 and NaNs. */ \
2087 } while (0)
2088
2089 float nan_a = std::numeric_limits<float>::quiet_NaN();
2090 float nan_b = std::numeric_limits<float>::quiet_NaN();
2091
2092 CHECK_MINMAX(1.0f, -1.0f, -1.0f, 1.0f);
2093 CHECK_MINMAX(-1.0f, 1.0f, -1.0f, 1.0f);
2094 CHECK_MINMAX(0.0f, -1.0f, -1.0f, 0.0f);
2095 CHECK_MINMAX(-1.0f, 0.0f, -1.0f, 0.0f);
2096 CHECK_MINMAX(-0.0f, -1.0f, -1.0f, -0.0f);
2097 CHECK_MINMAX(-1.0f, -0.0f, -1.0f, -0.0f);
2098 CHECK_MINMAX(0.0f, 1.0f, 0.0f, 1.0f);
2099 CHECK_MINMAX(1.0f, 0.0f, 0.0f, 1.0f);
2100
2101 CHECK_MINMAX(0.0f, 0.0f, 0.0f, 0.0f);
2102 CHECK_MINMAX(-0.0f, -0.0f, -0.0f, -0.0f);
2103 CHECK_MINMAX(-0.0f, 0.0f, -0.0f, 0.0f);
2104 CHECK_MINMAX(0.0f, -0.0f, -0.0f, 0.0f);
2105
2106 CHECK_MINMAX(0.0f, nan_a, nan_a, nan_a);
2107 CHECK_MINMAX(nan_a, 0.0f, nan_a, nan_a);
2108 CHECK_MINMAX(nan_a, nan_b, nan_a, nan_a);
2109 CHECK_MINMAX(nan_b, nan_a, nan_b, nan_b);
2110
2111 #undef CHECK_MINMAX
2112 }
2113
2114 template <typename T, typename Inputs, typename Results>
2115 static ::F4 GenerateMacroFloat64MinMax(MacroAssembler* masm) {
2116 T a = T::from_code(4); // f4
2117 T b = T::from_code(6); // f6
2118 T c = T::from_code(8); // f8
2119
2120 Label ool_min_abc, ool_min_aab, ool_min_aba;
2121 Label ool_max_abc, ool_max_aab, ool_max_aba;
2122
2123 Label done_min_abc, done_min_aab, done_min_aba;
2124 Label done_max_abc, done_max_aab, done_max_aba;
2125
2126 #define FLOAT_MIN_MAX(fminmax, res, x, y, done, ool, res_field) \
2127 __ ldc1(x, MemOperand(a0, offsetof(Inputs, src1_))); \
2128 __ ldc1(y, MemOperand(a0, offsetof(Inputs, src2_))); \
2129 __ fminmax(res, x, y, &ool); \
2130 __ bind(&done); \
2131 __ sdc1(a, MemOperand(a1, offsetof(Results, res_field)))
2132
2133 // a = min(b, c);
2134 FLOAT_MIN_MAX(Float64Min, a, b, c, done_min_abc, ool_min_abc, min_abc_);
2135 // a = min(a, b);
2136 FLOAT_MIN_MAX(Float64Min, a, a, b, done_min_aab, ool_min_aab, min_aab_);
2137 // a = min(b, a);
2138 FLOAT_MIN_MAX(Float64Min, a, b, a, done_min_aba, ool_min_aba, min_aba_);
2139
2140 // a = max(b, c);
2141 FLOAT_MIN_MAX(Float64Max, a, b, c, done_max_abc, ool_max_abc, max_abc_);
2142 // a = max(a, b);
2143 FLOAT_MIN_MAX(Float64Max, a, a, b, done_max_aab, ool_max_aab, max_aab_);
2144 // a = max(b, a);
2145 FLOAT_MIN_MAX(Float64Max, a, b, a, done_max_aba, ool_max_aba, max_aba_);
2146
2147 #undef FLOAT_MIN_MAX
2148
2149 __ jr(ra);
2150 __ nop();
2151
2152 // Generate out-of-line cases.
2153 __ bind(&ool_min_abc);
2154 __ Float64MinOutOfLine(a, b, c);
2155 __ b(&done_min_abc);
2156
2157 __ bind(&ool_min_aab);
2158 __ Float64MinOutOfLine(a, a, b);
2159 __ b(&done_min_aab);
2160
2161 __ bind(&ool_min_aba);
2162 __ Float64MinOutOfLine(a, b, a);
2163 __ b(&done_min_aba);
2164
2165 __ bind(&ool_max_abc);
2166 __ Float64MaxOutOfLine(a, b, c);
2167 __ b(&done_max_abc);
2168
2169 __ bind(&ool_max_aab);
2170 __ Float64MaxOutOfLine(a, a, b);
2171 __ b(&done_max_aab);
2172
2173 __ bind(&ool_max_aba);
2174 __ Float64MaxOutOfLine(a, b, a);
2175 __ b(&done_max_aba);
2176
2177 CodeDesc desc;
2178 masm->GetCode(&desc);
2179 Handle<Code> code = masm->isolate()->factory()->NewCode(
2180 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
2181 #ifdef DEBUG
2182 OFStream os(stdout);
2183 code->Print(os);
2184 #endif
2185 return FUNCTION_CAST<::F4>(code->entry());
2186 }
2187
2188 TEST(macro_float_minmax_f64) {
2189 // Test the Float64Min and Float64Max macros.
2190 CcTest::InitializeVM();
2191 Isolate* isolate = CcTest::i_isolate();
2192 HandleScope scope(isolate);
2193
2194 MacroAssembler assembler(isolate, NULL, 0,
2195 v8::internal::CodeObjectRequired::kYes);
2196 MacroAssembler* masm = &assembler;
2197
2198 struct Inputs {
2199 double src1_;
2200 double src2_;
2201 };
2202
2203 struct Results {
2204 // Check all register aliasing possibilities in order to exercise all
2205 // code-paths in the macro assembler.
2206 double min_abc_;
2207 double min_aab_;
2208 double min_aba_;
2209 double max_abc_;
2210 double max_aab_;
2211 double max_aba_;
2212 };
2213
2214 ::F4 f = GenerateMacroFloat64MinMax<DoubleRegister, Inputs, Results>(masm);
2215 Object* dummy = nullptr;
2216 USE(dummy);
2217
2218 #define CHECK_MINMAX(src1, src2, min, max) \
2219 do { \
2220 Inputs inputs = {src1, src2}; \
2221 Results results; \
2222 dummy = CALL_GENERATED_CODE(isolate, f, &inputs, &results, 0, 0, 0); \
2223 CHECK_EQ(bit_cast<uint64_t>(min), bit_cast<uint64_t>(results.min_abc_)); \
2224 CHECK_EQ(bit_cast<uint64_t>(min), bit_cast<uint64_t>(results.min_aab_)); \
2225 CHECK_EQ(bit_cast<uint64_t>(min), bit_cast<uint64_t>(results.min_aba_)); \
2226 CHECK_EQ(bit_cast<uint64_t>(max), bit_cast<uint64_t>(results.max_abc_)); \
2227 CHECK_EQ(bit_cast<uint64_t>(max), bit_cast<uint64_t>(results.max_aab_)); \
2228 CHECK_EQ(bit_cast<uint64_t>(max), bit_cast<uint64_t>(results.max_aba_)); \
2229 /* Use a bit_cast to correctly identify -0.0 and NaNs. */ \
2230 } while (0)
2231
2232 double nan_a = std::numeric_limits<double>::quiet_NaN();
2233 double nan_b = std::numeric_limits<double>::quiet_NaN();
2234
2235 CHECK_MINMAX(1.0, -1.0, -1.0, 1.0);
2236 CHECK_MINMAX(-1.0, 1.0, -1.0, 1.0);
2237 CHECK_MINMAX(0.0, -1.0, -1.0, 0.0);
2238 CHECK_MINMAX(-1.0, 0.0, -1.0, 0.0);
2239 CHECK_MINMAX(-0.0, -1.0, -1.0, -0.0);
2240 CHECK_MINMAX(-1.0, -0.0, -1.0, -0.0);
2241 CHECK_MINMAX(0.0, 1.0, 0.0, 1.0);
2242 CHECK_MINMAX(1.0, 0.0, 0.0, 1.0);
2243
2244 CHECK_MINMAX(0.0, 0.0, 0.0, 0.0);
2245 CHECK_MINMAX(-0.0, -0.0, -0.0, -0.0);
2246 CHECK_MINMAX(-0.0, 0.0, -0.0, 0.0);
2247 CHECK_MINMAX(0.0, -0.0, -0.0, 0.0);
2248
2249 CHECK_MINMAX(0.0, nan_a, nan_a, nan_a);
2250 CHECK_MINMAX(nan_a, 0.0, nan_a, nan_a);
2251 CHECK_MINMAX(nan_a, nan_b, nan_a, nan_a);
2252 CHECK_MINMAX(nan_b, nan_a, nan_b, nan_b);
2253
2254 #undef CHECK_MINMAX
2255 }
2256
1970 #undef __ 2257 #undef __
OLDNEW
« no previous file with comments | « test/cctest/test-macro-assembler-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698