opcodes: avoid undefined operations on signed ints
authorWim Taymans <wtaymans@redhat.com>
Wed, 17 Sep 2014 14:06:35 +0000 (16:06 +0200)
committerWim Taymans <wtaymans@redhat.com>
Wed, 17 Sep 2014 14:06:35 +0000 (16:06 +0200)
Cast to unsigned int when doing addition and subtraction that can
overflow.
Cast to unsigned int when doing the lower part of a multiplication.
Cast to unsigned int when doing left shifts into the sign bit.
Regenerate the emulation code. This should avoid multiple warnings
reported with clang and -fsanitize=undefined.

See https://bugzilla.gnome.org/show_bug.cgi?id=728738

orc/opcodes.h
orc/orcemulateopcodes.c
orc/orcprogram-c.c

index df428a9..6cbcd66 100644 (file)
@@ -17,7 +17,7 @@ BINARY_SB(mullb, "(%s * %s) & 0xff")
 BINARY_SB(mulhsb, "(%s * %s) >> 8")
 BINARY_UB(mulhub, "((orc_uint32)(orc_uint8)%s * (orc_uint32)(orc_uint8)%s) >> 8")
 BINARY_SB(orb, "%s | %s")
-BINARY_SB(shlb, "%s << %s")
+BINARY_SB(shlb, "((orc_uint8)%s) << %s")
 BINARY_SB(shrsb, "%s >> %s")
 BINARY_UB(shrub, "((orc_uint8)%s) >> %s")
 UNARY_SB(signb, "ORC_CLAMP(%s,-1,1)")
@@ -45,7 +45,7 @@ BINARY_SW(mullw, "(%s * %s) & 0xffff")
 BINARY_SW(mulhsw, "(%s * %s) >> 16")
 BINARY_UW(mulhuw, "((orc_uint32)((orc_uint16)%s) * (orc_uint32)((orc_uint16)%s)) >> 16")
 BINARY_SW(orw, "%s | %s")
-BINARY_SW(shlw, "%s << %s")
+BINARY_SW(shlw, "((orc_uint16)%s) << %s")
 BINARY_SW(shrsw, "%s >> %s")
 BINARY_UW(shruw, "((orc_uint16)%s) >> %s")
 UNARY_SW(signw, "ORC_CLAMP(%s,-1,1)")
@@ -55,7 +55,7 @@ BINARY_UW(subusw, "ORC_CLAMP_UW((orc_uint16)%s - (orc_uint16)%s)")
 BINARY_SW(xorw, "%s ^ %s")
 
 UNARY_SL(absl, "ORC_ABS(%s)")
-BINARY_SL(addl, "%s + %s")
+BINARY_SL(addl, "((orc_uint32)%s) + ((orc_uint32)%s)")
 BINARY_SL(addssl, "ORC_CLAMP_SL((orc_int64)%s + (orc_int64)%s)")
 BINARY_UL(addusl, "ORC_CLAMP_UL((orc_int64)(orc_uint32)%s + (orc_int64)(orc_uint32)%s)")
 BINARY_SL(andl, "%s & %s")
@@ -69,15 +69,15 @@ BINARY_SL(maxsl, "ORC_MAX(%s, %s)")
 BINARY_UL(maxul, "ORC_MAX((orc_uint32)%s, (orc_uint32)%s)")
 BINARY_SL(minsl, "ORC_MIN(%s, %s)")
 BINARY_UL(minul, "ORC_MIN((orc_uint32)%s, (orc_uint32)%s)")
-BINARY_SL(mulll, "(%s * %s) & 0xffffffff")
+BINARY_SL(mulll, "(((orc_uint32)%s) * ((orc_uint32)%s)) & 0xffffffff")
 BINARY_SL(mulhsl, "((orc_int64)%s * (orc_int64)%s) >> 32")
 BINARY_UL(mulhul, "((orc_uint64)(orc_uint32)%s * (orc_uint64)(orc_uint32)%s) >> 32")
 BINARY_SL(orl, "%s | %s")
-BINARY_SL(shll, "%s << %s")
+BINARY_SL(shll, "((orc_uint32)%s) << %s")
 BINARY_SL(shrsl, "%s >> %s")
 BINARY_UL(shrul, "((orc_uint32)%s) >> %s")
 UNARY_SL(signl, "ORC_CLAMP(%s,-1,1)")
-BINARY_SL(subl, "%s - %s")
+BINARY_SL(subl, "((orc_uint32)%s) - ((orc_uint32)%s)")
 BINARY_SL(subssl, "ORC_CLAMP_SL((orc_int64)%s - (orc_int64)%s)")
 BINARY_UL(subusl, "ORC_CLAMP_UL((orc_int64)(orc_uint32)%s - (orc_int64)(orc_uint32)%s)")
 BINARY_SL(xorl, "%s ^ %s")
@@ -89,9 +89,9 @@ BINARY_SQ(andq, "%s & %s")
 BINARY_SQ(andnq, "(~%s) & %s")
 BINARY_SQ(orq, "%s | %s")
 BINARY_SQ(xorq, "%s ^ %s")
-BINARY_SQ(addq, "%s + %s")
-BINARY_SQ(subq, "%s - %s")
-BINARY_SQ(shlq, "%s << %s")
+BINARY_SQ(addq, "((orc_uint64)%s) + ((orc_uint64)%s)")
+BINARY_SQ(subq, "((orc_uint64)%s) - ((orc_uint64)%s)")
+BINARY_SQ(shlq, "((orc_uint64)%s) << %s")
 BINARY_SQ(shrsq, "%s >> %s")
 BINARY_UQ(shruq, "((orc_uint64)%s) >> %s")
 
@@ -122,9 +122,9 @@ UNARY_LW(convussql, "ORC_CLAMP_SL((orc_uint64)%s)")
 UNARY_LW(convuusql, "ORC_CLAMP_UL((orc_uint64)%s)")
 
 BINARY_BW(mulsbw, "%s * %s")
-BINARY_BW(mulubw, "((orc_uint8)%s) * ((orc_uint8)%s)")
+BINARY_BW(mulubw, "((orc_uint16)((orc_uint8)%s)) * ((orc_uint16)((orc_uint8)%s))")
 BINARY_WL(mulswl, "%s * %s")
-BINARY_WL(muluwl, "((orc_uint16)%s) * ((orc_uint16)%s)")
+BINARY_WL(muluwl, "((orc_uint32)((orc_uint16)%s)) * ((orc_uint32)((orc_uint16)%s))")
 BINARY_LQ(mulslq, "((orc_int64)%s) * ((orc_int64)%s)")
 BINARY_LQ(mululq, "((orc_uint64)((orc_uint32)%s)) * ((orc_uint64)((orc_uint32)%s))")
 
index 6724432..e80fce2 100644 (file)
@@ -807,7 +807,7 @@ emulate_shlb (OrcOpcodeExecutor *ex, int offset, int n)
     /* 0: loadb */
     var32 = ptr4[i];
     /* 1: shlb */
-    var33 = var32 << ((orc_union64 *)(ex->src_ptrs[1]))->i;
+    var33 = ((orc_uint8)var32) << ((orc_union64 *)(ex->src_ptrs[1]))->i;
     /* 2: storeb */
     ptr0[i] = var33;
   }
@@ -1695,7 +1695,7 @@ emulate_shlw (OrcOpcodeExecutor *ex, int offset, int n)
     /* 0: loadw */
     var32 = ptr4[i];
     /* 1: shlw */
-    var33.i = var32.i << ((orc_union64 *)(ex->src_ptrs[1]))->i;
+    var33.i = ((orc_uint16)var32.i) << ((orc_union64 *)(ex->src_ptrs[1]))->i;
     /* 2: storew */
     ptr0[i] = var33;
   }
@@ -1957,7 +1957,7 @@ emulate_addl (OrcOpcodeExecutor *ex, int offset, int n)
     /* 1: loadl */
     var33 = ptr5[i];
     /* 2: addl */
-    var34.i = var32.i + var33.i;
+    var34.i = ((orc_uint32)var32.i) + ((orc_uint32)var33.i);
     /* 3: storel */
     ptr0[i] = var34;
   }
@@ -2419,7 +2419,7 @@ emulate_mulll (OrcOpcodeExecutor *ex, int offset, int n)
     /* 1: loadl */
     var33 = ptr5[i];
     /* 2: mulll */
-    var34.i = (var32.i * var33.i) & 0xffffffff;
+    var34.i = (((orc_uint32)var32.i) * ((orc_uint32)var33.i)) & 0xffffffff;
     /* 3: storel */
     ptr0[i] = var34;
   }
@@ -2530,7 +2530,7 @@ emulate_shll (OrcOpcodeExecutor *ex, int offset, int n)
     /* 0: loadl */
     var32 = ptr4[i];
     /* 1: shll */
-    var33.i = var32.i << ((orc_union64 *)(ex->src_ptrs[1]))->i;
+    var33.i = ((orc_uint32)var32.i) << ((orc_union64 *)(ex->src_ptrs[1]))->i;
     /* 2: storel */
     ptr0[i] = var33;
   }
@@ -2652,7 +2652,7 @@ emulate_subl (OrcOpcodeExecutor *ex, int offset, int n)
     /* 1: loadl */
     var33 = ptr5[i];
     /* 2: subl */
-    var34.i = var32.i - var33.i;
+    var34.i = ((orc_uint32)var32.i) - ((orc_uint32)var33.i);
     /* 3: storel */
     ptr0[i] = var34;
   }
@@ -3051,7 +3051,7 @@ emulate_addq (OrcOpcodeExecutor *ex, int offset, int n)
     /* 1: loadq */
     var33 = ptr5[i];
     /* 2: addq */
-    var34.i = var32.i + var33.i;
+    var34.i = ((orc_uint64)var32.i) + ((orc_uint64)var33.i);
     /* 3: storeq */
     ptr0[i] = var34;
   }
@@ -3080,7 +3080,7 @@ emulate_subq (OrcOpcodeExecutor *ex, int offset, int n)
     /* 1: loadq */
     var33 = ptr5[i];
     /* 2: subq */
-    var34.i = var32.i - var33.i;
+    var34.i = ((orc_uint64)var32.i) - ((orc_uint64)var33.i);
     /* 3: storeq */
     ptr0[i] = var34;
   }
@@ -3104,7 +3104,7 @@ emulate_shlq (OrcOpcodeExecutor *ex, int offset, int n)
     /* 0: loadq */
     var32 = ptr4[i];
     /* 1: shlq */
-    var33.i = var32.i << ((orc_union64 *)(ex->src_ptrs[1]))->i;
+    var33.i = ((orc_uint64)var32.i) << ((orc_union64 *)(ex->src_ptrs[1]))->i;
     /* 2: storeq */
     ptr0[i] = var33;
   }
@@ -3248,7 +3248,7 @@ emulate_splatbl (OrcOpcodeExecutor *ex, int offset, int n)
     /* 0: loadb */
     var32 = ptr4[i];
     /* 1: splatbl */
-    var33.i = ((var32&0xff) << 24) | ((var32&0xff)<<16) | ((var32&0xff) << 8) | (var32&0xff);
+    var33.i = ((((orc_uint32)var32)&0xff) << 24) | ((((orc_uint32)var32)&0xff)<<16) | ((((orc_uint32)var32)&0xff) << 8) | (((orc_uint32)var32)&0xff);
     /* 2: storel */
     ptr0[i] = var33;
   }
@@ -3810,7 +3810,7 @@ emulate_mulubw (OrcOpcodeExecutor *ex, int offset, int n)
     /* 1: loadb */
     var33 = ptr5[i];
     /* 2: mulubw */
-    var34.i = ((orc_uint8)var32) * ((orc_uint8)var33);
+    var34.i = ((orc_uint16)((orc_uint8)var32)) * ((orc_uint16)((orc_uint8)var33));
     /* 3: storew */
     ptr0[i] = var34;
   }
@@ -3868,7 +3868,7 @@ emulate_muluwl (OrcOpcodeExecutor *ex, int offset, int n)
     /* 1: loadw */
     var33 = ptr5[i];
     /* 2: muluwl */
-    var34.i = ((orc_uint16)var32.i) * ((orc_uint16)var33.i);
+    var34.i = ((orc_uint32)((orc_uint16)var32.i)) * ((orc_uint32)((orc_uint16)var33.i));
     /* 3: storel */
     ptr0[i] = var34;
   }
@@ -3969,9 +3969,9 @@ emulate_accl (OrcOpcodeExecutor *ex, int offset, int n)
     /* 0: loadl */
     var32 = ptr4[i];
     /* 1: accl */
-    var12.i = var12.i + var32.i;
+    var12.i = ((orc_uint32)var12.i) + ((orc_uint32)var32.i);
   }
-  ((orc_union32 *)ex->dest_ptrs[0])->i += var12.i;
+  ((orc_union32 *)ex->dest_ptrs[0])->i += (orc_uint32)var12.i;
 
 }
 
@@ -3997,7 +3997,7 @@ emulate_accsadubl (OrcOpcodeExecutor *ex, int offset, int n)
     /* 2: accsadubl */
     var12.i = var12.i + ORC_ABS((orc_int32)(orc_uint8)var32 - (orc_int32)(orc_uint8)var33);
   }
-  ((orc_union32 *)ex->dest_ptrs[0])->i += var12.i;
+  ((orc_union32 *)ex->dest_ptrs[0])->i += (orc_uint32)var12.i;
 
 }
 
index 2afb0cf..02b5aa8 100644 (file)
@@ -441,8 +441,8 @@ orc_compiler_c_assemble (OrcCompiler *compiler)
             ORC_ASM_CODE(compiler,"  *%s = %s;\n",
                 varnames[i], varname);
           } else if (compiler->target_flags & ORC_TARGET_C_OPCODE) {
-            ORC_ASM_CODE(compiler,"  ((orc_union32 *)ex->dest_ptrs[%d])->i += %s;\n",
-                i - ORC_VAR_A1, varname);
+            ORC_ASM_CODE(compiler,"  ((orc_union32 *)ex->dest_ptrs[%d])->i += (orc_uint%d)%s;\n",
+                i - ORC_VAR_A1, var->size * 8, varname);
           } else {
             ORC_ASM_CODE(compiler,"  ex->accumulators[%d] = %s;\n",
                 i - ORC_VAR_A1, varname);
@@ -1009,7 +1009,7 @@ c_rule_accl (OrcCompiler *p, void *user, OrcInstruction *insn)
   c_get_name_int (dest, p, insn, insn->dest_args[0]);
   c_get_name_int (src1, p, insn, insn->src_args[0]);
 
-  ORC_ASM_CODE(p,"    %s = %s + %s;\n", dest, dest, src1);
+  ORC_ASM_CODE(p,"    %s = ((orc_uint32)%s) + ((orc_uint32)%s);\n", dest, dest, src1);
 }
 
 static void
@@ -1187,7 +1187,8 @@ c_rule_splatbl (OrcCompiler *p, void *user, OrcInstruction *insn)
   c_get_name_int (src, p, insn, insn->src_args[0]);
 
   ORC_ASM_CODE(p,
-      "    %s = ((%s&0xff) << 24) | ((%s&0xff)<<16) | ((%s&0xff) << 8) | (%s&0xff);\n",
+      "    %s = ((((orc_uint32)%s)&0xff) << 24) | ((((orc_uint32)%s)&0xff)<<16)"
+      " | ((((orc_uint32)%s)&0xff) << 8) | (((orc_uint32)%s)&0xff);\n",
       dest, src, src, src, src);
 }