Rewrite Score extractors
authorRon Britvich <ron@britvich.com>
Mon, 5 May 2014 06:52:14 +0000 (08:52 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Mon, 5 May 2014 07:05:29 +0000 (09:05 +0200)
Less tricky and even a bit faster. With this
version Visual Studio Ultimate 2013 Update 2 RC
runs fine even in O2 optimization.

No functional change.

src/types.h

index 9bfe9a4c2e18ce298590436206666beac36b022d..8cdb5227c0055efa4df754be4b30d0d0e0d2fa86 100644 (file)
@@ -267,17 +267,28 @@ enum Score {
   SCORE_ENSURE_INTEGER_SIZE_N = INT_MIN
 };
 
-inline Score make_score(int mg, int eg) { return Score((mg << 16) + eg); }
+typedef union {
+  uint32_t full;
+  struct { int16_t eg, mg; } half;
+} ScoreView;
+
+inline Score make_score(int mg, int eg) {
+  ScoreView v;
+  v.half.mg = (int16_t)mg - (uint16_t(eg) >> 15);
+  v.half.eg = (int16_t)eg;
+  return Score(v.full);
+}
 
-/// Extracting the signed lower and upper 16 bits is not so trivial because
-/// according to the standard a simple cast to short is implementation defined
-/// and so is a right shift of a signed integer.
 inline Value mg_value(Score s) {
-  return Value(((s + 0x8000) & ~0xffff) / 0x10000);
+  ScoreView v;
+  v.full = s;
+  return Value(v.half.mg + (uint16_t(v.half.eg) >> 15));
 }
 
 inline Value eg_value(Score s) {
-  return Value((int)(unsigned(s) & 0x7FFFU) - (int)(unsigned(s) & 0x8000U));
+  ScoreView v;
+  v.full = s;
+  return Value(v.half.eg);
 }
 
 #define ENABLE_BASE_OPERATORS_ON(T)                                         \