summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2014-09-17 16:06:35 +0200
committerWim Taymans <wtaymans@redhat.com>2014-09-17 16:06:35 +0200
commit45957a71c26285ee097029706100e8555ff6189f (patch)
treeebdfa41a731d60827af8d646a38c47a2aee9eb88
parent4a7f1c0c1d9418e7d220110c5a0ec732f755c284 (diff)
opcodes: avoid undefined operations on signed ints
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
-rw-r--r--orc/opcodes.h22
-rw-r--r--orc/orcemulateopcodes.c30
-rw-r--r--orc/orcprogram-c.c9
3 files changed, 31 insertions, 30 deletions
diff --git a/orc/opcodes.h b/orc/opcodes.h
index df428a9..6cbcd66 100644
--- a/orc/opcodes.h
+++ b/orc/opcodes.h
@@ -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))")
diff --git a/orc/orcemulateopcodes.c b/orc/orcemulateopcodes.c
index 6724432..e80fce2 100644
--- a/orc/orcemulateopcodes.c
+++ b/orc/orcemulateopcodes.c
@@ -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;
}
diff --git a/orc/orcprogram-c.c b/orc/orcprogram-c.c
index 2afb0cf..02b5aa8 100644
--- a/orc/orcprogram-c.c
+++ b/orc/orcprogram-c.c
@@ -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);
}