diff options
author | Wim Taymans <wtaymans@redhat.com> | 2014-09-17 16:06:35 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2014-09-17 16:06:35 +0200 |
commit | 45957a71c26285ee097029706100e8555ff6189f (patch) | |
tree | ebdfa41a731d60827af8d646a38c47a2aee9eb88 | |
parent | 4a7f1c0c1d9418e7d220110c5a0ec732f755c284 (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.h | 22 | ||||
-rw-r--r-- | orc/orcemulateopcodes.c | 30 | ||||
-rw-r--r-- | orc/orcprogram-c.c | 9 |
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); } |