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

Side by Side Diff: runtime/vm/simulator_dbc.cc

Issue 2341683003: DBC: Double converstion instructions (Closed)
Patch Set: Float32 typed data stores. Cleanup. Created 4 years, 3 months 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 | « runtime/vm/intermediate_language_dbc.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 (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include <setjmp.h> // NOLINT 5 #include <setjmp.h> // NOLINT
6 #include <stdlib.h> 6 #include <stdlib.h>
7 7
8 #include "vm/globals.h" 8 #include "vm/globals.h"
9 #if defined(TARGET_ARCH_DBC) 9 #if defined(TARGET_ARCH_DBC)
10 10
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 return static_cast<RawCode*>(FP[kPcMarkerSlotFromFp]); 244 return static_cast<RawCode*>(FP[kPcMarkerSlotFromFp]);
245 } 245 }
246 246
247 247
248 DART_FORCE_INLINE static void SetFrameCode(RawObject** FP, RawCode* code) { 248 DART_FORCE_INLINE static void SetFrameCode(RawObject** FP, RawCode* code) {
249 ASSERT(GetClassId(code) == kCodeCid); 249 ASSERT(GetClassId(code) == kCodeCid);
250 FP[kPcMarkerSlotFromFp] = code; 250 FP[kPcMarkerSlotFromFp] = code;
251 } 251 }
252 252
253 DART_FORCE_INLINE static uint8_t* GetTypedData( 253 DART_FORCE_INLINE static uint8_t* GetTypedData(
254 RawObject* obj, RawObject* index, intptr_t scale) { 254 RawObject* obj, RawObject* index) {
255 ASSERT(RawObject::IsTypedDataClassId(obj->GetClassId())); 255 ASSERT(RawObject::IsTypedDataClassId(obj->GetClassId()));
256 RawTypedData* array = reinterpret_cast<RawTypedData*>(obj); 256 RawTypedData* array = reinterpret_cast<RawTypedData*>(obj);
257 const intptr_t byte_offset = Smi::Value(RAW_CAST(Smi, index)); 257 const intptr_t byte_offset = Smi::Value(RAW_CAST(Smi, index));
258 ASSERT(byte_offset >= 0); 258 ASSERT(byte_offset >= 0);
259 return array->ptr()->data() + byte_offset; 259 return array->ptr()->data() + byte_offset;
260 } 260 }
261 }; 261 };
262 262
263 263
264 DART_FORCE_INLINE static uint32_t* SavedCallerPC(RawObject** FP) { 264 DART_FORCE_INLINE static uint32_t* SavedCallerPC(RawObject** FP) {
(...skipping 1697 matching lines...) Expand 10 before | Expand all | Expand 10 after
1962 1962
1963 { 1963 {
1964 BYTECODE(DMax, A_B_C); 1964 BYTECODE(DMax, A_B_C);
1965 const double lhs = bit_cast<double, RawObject*>(FP[rB]); 1965 const double lhs = bit_cast<double, RawObject*>(FP[rB]);
1966 const double rhs = bit_cast<double, RawObject*>(FP[rC]); 1966 const double rhs = bit_cast<double, RawObject*>(FP[rC]);
1967 FP[rA] = bit_cast<RawObject*, double>(fmax(lhs, rhs)); 1967 FP[rA] = bit_cast<RawObject*, double>(fmax(lhs, rhs));
1968 DISPATCH(); 1968 DISPATCH();
1969 } 1969 }
1970 1970
1971 { 1971 {
1972 BYTECODE(DTruncate, A_D);
1973 const double value = bit_cast<double, RawObject*>(FP[rD]);
1974 FP[rA] = bit_cast<RawObject*, double>(trunc(value));
1975 DISPATCH();
1976 }
1977
1978 {
1979 BYTECODE(DFloor, A_D);
1980 const double value = bit_cast<double, RawObject*>(FP[rD]);
1981 FP[rA] = bit_cast<RawObject*, double>(floor(value));
1982 DISPATCH();
1983 }
1984
1985 {
1986 BYTECODE(DCeil, A_D);
1987 const double value = bit_cast<double, RawObject*>(FP[rD]);
1988 FP[rA] = bit_cast<RawObject*, double>(ceil(value));
1989 DISPATCH();
1990 }
1991
1992 {
1993 BYTECODE(DoubleToFloat, A_D);
1994 const double value = bit_cast<double, RawObject*>(FP[rD]);
1995 const float valuef = static_cast<float>(value);
1996 *reinterpret_cast<float*>(&FP[rA]) = valuef;
1997 DISPATCH();
1998 }
1999
2000 {
2001 BYTECODE(FloatToDouble, A_D);
2002 const float valuef = *reinterpret_cast<float*>(&FP[rD]);
2003 const double value = static_cast<double>(valuef);
2004 FP[rA] = bit_cast<RawObject*, double>(value);
2005 DISPATCH();
2006 }
2007
2008 {
2009 BYTECODE(LoadIndexedFloat32, A_B_C);
2010 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rB], FP[rC]);
2011 const uint32_t value = *reinterpret_cast<uint32_t*>(data);
2012 const int64_t value64 = value;
Florian Schneider 2016/09/15 16:05:45 uint64_t?
zra 2016/09/15 16:18:21 Done.
2013 FP[rA] = reinterpret_cast<RawObject*>(value64);
2014 DISPATCH();
2015 }
2016
2017 {
2018 BYTECODE(LoadIndexed4Float32, A_B_C);
2019 ASSERT(RawObject::IsTypedDataClassId(FP[rB]->GetClassId()));
2020 RawTypedData* array = reinterpret_cast<RawTypedData*>(FP[rB]);
2021 RawSmi* index = RAW_CAST(Smi, FP[rC]);
2022 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
2023 const uint32_t value =
2024 reinterpret_cast<uint32_t*>(array->ptr()->data())[Smi::Value(index)];
2025 const int64_t value64 = value; // sign extend to clear high bits.
Florian Schneider 2016/09/15 16:05:45 uint64_t? The upper bits of the value that holds t
zra 2016/09/15 16:18:21 Done.
2026 FP[rA] = reinterpret_cast<RawObject*>(value64);
2027 DISPATCH();
2028 }
2029
2030 {
1972 BYTECODE(LoadIndexedFloat64, A_B_C); 2031 BYTECODE(LoadIndexedFloat64, A_B_C);
1973 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rB], FP[rC], 3); 2032 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rB], FP[rC]);
1974 *reinterpret_cast<uint64_t*>(&FP[rA]) = *reinterpret_cast<uint64_t*>(data); 2033 const int64_t value = *reinterpret_cast<uint64_t*>(data);
2034 FP[rA] = reinterpret_cast<RawObject*>(value);
1975 DISPATCH(); 2035 DISPATCH();
1976 } 2036 }
1977 2037
1978 { 2038 {
1979 BYTECODE(LoadIndexed8Float64, A_B_C); 2039 BYTECODE(LoadIndexed8Float64, A_B_C);
1980 ASSERT(RawObject::IsTypedDataClassId(FP[rB]->GetClassId())); 2040 ASSERT(RawObject::IsTypedDataClassId(FP[rB]->GetClassId()));
1981 RawTypedData* array = reinterpret_cast<RawTypedData*>(FP[rB]); 2041 RawTypedData* array = reinterpret_cast<RawTypedData*>(FP[rB]);
1982 RawSmi* index = RAW_CAST(Smi, FP[rC]); 2042 RawSmi* index = RAW_CAST(Smi, FP[rC]);
1983 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_)); 2043 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
1984 const int64_t value = 2044 const int64_t value =
1985 reinterpret_cast<int64_t*>(array->ptr()->data())[Smi::Value(index)]; 2045 reinterpret_cast<int64_t*>(array->ptr()->data())[Smi::Value(index)];
1986 FP[rA] = reinterpret_cast<RawObject*>(value); 2046 FP[rA] = reinterpret_cast<RawObject*>(value);
1987 DISPATCH(); 2047 DISPATCH();
1988 } 2048 }
1989 2049
1990 { 2050 {
2051 BYTECODE(StoreIndexedFloat32, A_B_C);
2052 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rA], FP[rB]);
2053 const uint64_t value = reinterpret_cast<uint64_t>(FP[rC]);
2054 const uint32_t value32 = value;
2055 *reinterpret_cast<uint32_t*>(data) = value32;
2056 DISPATCH();
2057 }
2058
2059 {
2060 BYTECODE(StoreIndexed4Float32, A_B_C);
2061 ASSERT(RawObject::IsTypedDataClassId(FP[rA]->GetClassId()));
2062 RawTypedData* array = reinterpret_cast<RawTypedData*>(FP[rA]);
2063 RawSmi* index = RAW_CAST(Smi, FP[rB]);
2064 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
2065 const uint64_t value = reinterpret_cast<uint64_t>(FP[rC]);
2066 const uint32_t value32 = value;
2067 reinterpret_cast<uint32_t*>(array->ptr()->data())[Smi::Value(index)] =
2068 value32;
2069 DISPATCH();
2070 }
2071
2072 {
1991 BYTECODE(StoreIndexedFloat64, A_B_C); 2073 BYTECODE(StoreIndexedFloat64, A_B_C);
1992 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rA], FP[rB], 3); 2074 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rA], FP[rB]);
1993 *reinterpret_cast<uint64_t*>(data) = reinterpret_cast<uint64_t>(FP[rC]); 2075 *reinterpret_cast<uint64_t*>(data) = reinterpret_cast<uint64_t>(FP[rC]);
1994 DISPATCH(); 2076 DISPATCH();
1995 } 2077 }
1996 2078
1997 { 2079 {
1998 BYTECODE(StoreIndexed8Float64, A_B_C); 2080 BYTECODE(StoreIndexed8Float64, A_B_C);
1999 ASSERT(RawObject::IsTypedDataClassId(FP[rA]->GetClassId())); 2081 ASSERT(RawObject::IsTypedDataClassId(FP[rA]->GetClassId()));
2000 RawTypedData* array = reinterpret_cast<RawTypedData*>(FP[rA]); 2082 RawTypedData* array = reinterpret_cast<RawTypedData*>(FP[rA]);
2001 RawSmi* index = RAW_CAST(Smi, FP[rB]); 2083 RawSmi* index = RAW_CAST(Smi, FP[rB]);
2002 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_)); 2084 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2119 DISPATCH(); 2201 DISPATCH();
2120 } 2202 }
2121 2203
2122 { 2204 {
2123 BYTECODE(DMax, A_B_C); 2205 BYTECODE(DMax, A_B_C);
2124 UNREACHABLE(); 2206 UNREACHABLE();
2125 DISPATCH(); 2207 DISPATCH();
2126 } 2208 }
2127 2209
2128 { 2210 {
2211 BYTECODE(DTruncate, A_D);
2212 UNREACHABLE();
2213 DISPATCH();
2214 }
2215
2216 {
2217 BYTECODE(DFloor, A_D);
2218 UNREACHABLE();
2219 DISPATCH();
2220 }
2221
2222 {
2223 BYTECODE(DCeil, A_D);
2224 UNREACHABLE();
2225 DISPATCH();
2226 }
2227
2228 {
2229 BYTECODE(DoubleToFloat, A_D);
2230 UNREACHABLE();
2231 DISPATCH();
2232 }
2233
2234 {
2235 BYTECODE(FloatToDouble, A_D);
2236 UNREACHABLE();
2237 DISPATCH();
2238 }
2239
2240 {
2241 BYTECODE(LoadIndexedFloat32, A_B_C);
2242 UNREACHABLE();
2243 DISPATCH();
2244 }
2245
2246 {
2247 BYTECODE(LoadIndexed4Float32, A_B_C);
2248 UNREACHABLE();
2249 DISPATCH();
2250 }
2251
2252 {
2129 BYTECODE(LoadIndexedFloat64, A_B_C); 2253 BYTECODE(LoadIndexedFloat64, A_B_C);
2130 UNREACHABLE(); 2254 UNREACHABLE();
2131 DISPATCH(); 2255 DISPATCH();
2132 } 2256 }
2133 2257
2134 { 2258 {
2135 BYTECODE(LoadIndexed8Float64, A_B_C); 2259 BYTECODE(LoadIndexed8Float64, A_B_C);
2136 UNREACHABLE(); 2260 UNREACHABLE();
2137 DISPATCH(); 2261 DISPATCH();
2138 } 2262 }
2139 2263
2140 { 2264 {
2265 BYTECODE(StoreIndexedFloat32, A_B_C);
2266 UNREACHABLE();
2267 DISPATCH();
2268 }
2269
2270 {
2271 BYTECODE(StoreIndexed4Float32, A_B_C);
2272 UNREACHABLE();
2273 DISPATCH();
2274 }
2275
2276 {
2141 BYTECODE(StoreIndexedFloat64, A_B_C); 2277 BYTECODE(StoreIndexedFloat64, A_B_C);
2142 UNREACHABLE(); 2278 UNREACHABLE();
2143 DISPATCH(); 2279 DISPATCH();
2144 } 2280 }
2145 2281
2146 { 2282 {
2147 BYTECODE(StoreIndexed8Float64, A_B_C); 2283 BYTECODE(StoreIndexed8Float64, A_B_C);
2148 UNREACHABLE(); 2284 UNREACHABLE();
2149 DISPATCH(); 2285 DISPATCH();
2150 } 2286 }
(...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after
3036 RawArray* array = RAW_CAST(Array, FP[rA]); 3172 RawArray* array = RAW_CAST(Array, FP[rA]);
3037 RawSmi* index = RAW_CAST(Smi, FP[rB]); 3173 RawSmi* index = RAW_CAST(Smi, FP[rB]);
3038 RawObject* value = FP[rC]; 3174 RawObject* value = FP[rC];
3039 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_)); 3175 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
3040 array->StorePointer(array->ptr()->data() + Smi::Value(index), value); 3176 array->StorePointer(array->ptr()->data() + Smi::Value(index), value);
3041 DISPATCH(); 3177 DISPATCH();
3042 } 3178 }
3043 3179
3044 { 3180 {
3045 BYTECODE(StoreIndexedUint8, A_B_C); 3181 BYTECODE(StoreIndexedUint8, A_B_C);
3046 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rA], FP[rB], 0); 3182 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rA], FP[rB]);
3047 *data = Smi::Value(RAW_CAST(Smi, FP[rC])); 3183 *data = Smi::Value(RAW_CAST(Smi, FP[rC]));
3048 DISPATCH(); 3184 DISPATCH();
3049 } 3185 }
3050 3186
3051 { 3187 {
3052 BYTECODE(StoreIndexedExternalUint8, A_B_C); 3188 BYTECODE(StoreIndexedExternalUint8, A_B_C);
3053 uint8_t* array = reinterpret_cast<uint8_t*>(FP[rA]); 3189 uint8_t* array = reinterpret_cast<uint8_t*>(FP[rA]);
3054 RawSmi* index = RAW_CAST(Smi, FP[rB]); 3190 RawSmi* index = RAW_CAST(Smi, FP[rB]);
3055 RawSmi* value = RAW_CAST(Smi, FP[rC]); 3191 RawSmi* value = RAW_CAST(Smi, FP[rC]);
3056 array[Smi::Value(index)] = Smi::Value(value); 3192 array[Smi::Value(index)] = Smi::Value(value);
3057 DISPATCH(); 3193 DISPATCH();
3058 } 3194 }
3059 3195
3060 { 3196 {
3061 BYTECODE(StoreIndexedOneByteString, A_B_C); 3197 BYTECODE(StoreIndexedOneByteString, A_B_C);
3062 RawOneByteString* array = RAW_CAST(OneByteString, FP[rA]); 3198 RawOneByteString* array = RAW_CAST(OneByteString, FP[rA]);
3063 RawSmi* index = RAW_CAST(Smi, FP[rB]); 3199 RawSmi* index = RAW_CAST(Smi, FP[rB]);
3064 RawSmi* value = RAW_CAST(Smi, FP[rC]); 3200 RawSmi* value = RAW_CAST(Smi, FP[rC]);
3065 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_)); 3201 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
3066 array->ptr()->data()[Smi::Value(index)] = Smi::Value(value); 3202 array->ptr()->data()[Smi::Value(index)] = Smi::Value(value);
3067 DISPATCH(); 3203 DISPATCH();
3068 } 3204 }
3069 3205
3070 { 3206 {
3071 BYTECODE(StoreIndexedUint32, A_B_C); 3207 BYTECODE(StoreIndexedUint32, A_B_C);
3072 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rA], FP[rB], 2); 3208 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rA], FP[rB]);
3073 const uintptr_t value = reinterpret_cast<uintptr_t>(FP[rC]); 3209 const uintptr_t value = reinterpret_cast<uintptr_t>(FP[rC]);
3074 *reinterpret_cast<uint32_t*>(data) = static_cast<uint32_t>(value); 3210 *reinterpret_cast<uint32_t*>(data) = static_cast<uint32_t>(value);
3075 DISPATCH(); 3211 DISPATCH();
3076 } 3212 }
3077 3213
3078 { 3214 {
3079 BYTECODE(LoadIndexed, A_B_C); 3215 BYTECODE(LoadIndexed, A_B_C);
3080 RawObject* obj = FP[rB]; 3216 RawObject* obj = FP[rB];
3081 ASSERT(obj->IsArray() || obj->IsImmutableArray()); 3217 ASSERT(obj->IsArray() || obj->IsImmutableArray());
3082 RawArray* array = reinterpret_cast<RawArray*>(obj); 3218 RawArray* array = reinterpret_cast<RawArray*>(obj);
3083 RawSmi* index = RAW_CAST(Smi, FP[rC]); 3219 RawSmi* index = RAW_CAST(Smi, FP[rC]);
3084 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_)); 3220 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
3085 FP[rA] = array->ptr()->data()[Smi::Value(index)]; 3221 FP[rA] = array->ptr()->data()[Smi::Value(index)];
3086 DISPATCH(); 3222 DISPATCH();
3087 } 3223 }
3088 3224
3089 { 3225 {
3090 BYTECODE(LoadIndexedUint8, A_B_C); 3226 BYTECODE(LoadIndexedUint8, A_B_C);
3091 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rB], FP[rC], 0); 3227 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rB], FP[rC]);
3092 FP[rA] = Smi::New(*data); 3228 FP[rA] = Smi::New(*data);
3093 DISPATCH(); 3229 DISPATCH();
3094 } 3230 }
3095 3231
3096 { 3232 {
3097 BYTECODE(LoadIndexedInt8, A_B_C); 3233 BYTECODE(LoadIndexedInt8, A_B_C);
3098 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rB], FP[rC], 0); 3234 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rB], FP[rC]);
3099 FP[rA] = Smi::New(*reinterpret_cast<int8_t*>(data)); 3235 FP[rA] = Smi::New(*reinterpret_cast<int8_t*>(data));
3100 DISPATCH(); 3236 DISPATCH();
3101 } 3237 }
3102 3238
3103 { 3239 {
3104 BYTECODE(LoadIndexedUint32, A_B_C); 3240 BYTECODE(LoadIndexedUint32, A_B_C);
3105 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rB], FP[rC], 2); 3241 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rB], FP[rC]);
3106 FP[rA] = reinterpret_cast<RawObject*>(*reinterpret_cast<uintptr_t*>(data)); 3242 FP[rA] = reinterpret_cast<RawObject*>(*reinterpret_cast<uintptr_t*>(data));
3107 DISPATCH(); 3243 DISPATCH();
3108 } 3244 }
3109 3245
3110 { 3246 {
3111 BYTECODE(LoadIndexedInt32, A_B_C); 3247 BYTECODE(LoadIndexedInt32, A_B_C);
3112 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rB], FP[rC], 2); 3248 uint8_t* data = SimulatorHelpers::GetTypedData(FP[rB], FP[rC]);
3113 FP[rA] = reinterpret_cast<RawObject*>(*reinterpret_cast<intptr_t*>(data)); 3249 FP[rA] = reinterpret_cast<RawObject*>(*reinterpret_cast<intptr_t*>(data));
3114 DISPATCH(); 3250 DISPATCH();
3115 } 3251 }
3116 3252
3117 { 3253 {
3118 BYTECODE(LoadIndexedExternalUint8, A_B_C); 3254 BYTECODE(LoadIndexedExternalUint8, A_B_C);
3119 uint8_t* data = reinterpret_cast<uint8_t*>(FP[rB]); 3255 uint8_t* data = reinterpret_cast<uint8_t*>(FP[rB]);
3120 RawSmi* index = RAW_CAST(Smi, FP[rC]); 3256 RawSmi* index = RAW_CAST(Smi, FP[rC]);
3121 FP[rA] = Smi::New(data[Smi::Value(index)]); 3257 FP[rA] = Smi::New(data[Smi::Value(index)]);
3122 DISPATCH(); 3258 DISPATCH();
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
3327 pc_ = pc; 3463 pc_ = pc;
3328 special_[kExceptionSpecialIndex] = raw_exception; 3464 special_[kExceptionSpecialIndex] = raw_exception;
3329 special_[kStacktraceSpecialIndex] = raw_stacktrace; 3465 special_[kStacktraceSpecialIndex] = raw_stacktrace;
3330 buf->Longjmp(); 3466 buf->Longjmp();
3331 UNREACHABLE(); 3467 UNREACHABLE();
3332 } 3468 }
3333 3469
3334 } // namespace dart 3470 } // namespace dart
3335 3471
3336 #endif // defined TARGET_ARCH_DBC 3472 #endif // defined TARGET_ARCH_DBC
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_dbc.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698