diff --git a/libc3/integer.c b/libc3/integer.c
index 90d21f0..8b56ec9 100644
--- a/libc3/integer.c
+++ b/libc3/integer.c
@@ -170,6 +170,20 @@ s_integer * integer_init_double (s_integer *a, double x)
return integer_set_double(a, x);
}
+s_integer * integer_init_s8 (s_integer *a, s8 x)
+{
+ assert(a);
+ integer_init(a);
+ return integer_set_s32(a, x);
+}
+
+s_integer * integer_init_s16 (s_integer *a, s16 x)
+{
+ assert(a);
+ integer_init(a);
+ return integer_set_s32(a, x);
+}
+
s_integer * integer_init_s32 (s_integer *a, s32 x)
{
assert(a);
@@ -191,6 +205,20 @@ s_integer * integer_init_sw (s_integer *a, sw x)
return integer_set_sw(a, x);
}
+s_integer * integer_init_u8 (s_integer *a, u8 x)
+{
+ assert(a);
+ integer_init(a);
+ return integer_set_u32(a, x);
+}
+
+s_integer * integer_init_u16 (s_integer *a, u16 x)
+{
+ assert(a);
+ integer_init(a);
+ return integer_set_u32(a, x);
+}
+
s_integer * integer_init_u32 (s_integer *a, u32 x)
{
assert(a);
diff --git a/libc3/integer.h b/libc3/integer.h
index 18a43a9..2c8db35 100644
--- a/libc3/integer.h
+++ b/libc3/integer.h
@@ -29,9 +29,13 @@
s_integer * integer_init (s_integer *i);
s_integer * integer_init_1 (s_integer *i, const s8 *p);
s_integer * integer_init_double (s_integer *a, double x);
+s_integer * integer_init_s8 (s_integer *a, s8 x);
+s_integer * integer_init_s16 (s_integer *a, s16 x);
s_integer * integer_init_s32 (s_integer *a, s32 x);
s_integer * integer_init_s64 (s_integer *a, s64 x);
s_integer * integer_init_sw (s_integer *a, sw x);
+s_integer * integer_init_u8 (s_integer *a, u8 x);
+s_integer * integer_init_u16 (s_integer *a, u16 x);
s_integer * integer_init_u32 (s_integer *a, u32 x);
s_integer * integer_init_u64 (s_integer *a, u64 x);
s_integer * integer_init_uw (s_integer *a, uw x);
diff --git a/libc3/tag.c b/libc3/tag.c
index a35fba1..418c025 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -549,7 +549,7 @@ s_tag * tag_add (const s_tag *a, const s_tag *b, s_tag *dest)
return tag_init_u32(dest, (u32) a->data.u8 + b->data.u32);
case TAG_U64:
if (a->data.u8 > U64_MAX - b->data.u64) {
- integer_init_u32(&tmp, (u32) a->data.u8);
+ integer_init_u8(&tmp, a->data.u8);
integer_init_u64(&tmp2, b->data.u64);
tag_init_integer_zero(dest);
integer_add(&tmp, &tmp2, &dest->data.integer);
@@ -644,21 +644,59 @@ s_tag * tag_add (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
return dest;
case TAG_S8:
- return tag_init_s32(dest, (s32) a->data.u32 + (s32) b->data.s8);
+ if ((s64) a->data.u32 > S32_MAX - b->data.s8)
+ return tag_init_s64(dest, (s64) a->data.u32 + (s64) b->data.s8);
+ else
+ return tag_init_s32(dest, (s32) a->data.u32 + (s32) b->data.s8);
case TAG_S16:
- return tag_init_s32(dest, (s32) a->data.u32 + (s32) b->data.s16);
+ if ((s64) a->data.u32 > S32_MAX - b->data.s16)
+ return tag_init_s64(dest, (s64) a->data.u32 + (s64) b->data.s16);
+ else
+ return tag_init_s32(dest, (s32) a->data.u32 + (s32) b->data.s16);
case TAG_S32:
- return tag_init_s32(dest, (s32) a->data.u32 + b->data.s32);
+ if ((s64) a->data.u32 > S32_MAX - b->data.s32)
+ return tag_init_s64(dest, (s64) a->data.u32 + (s64) b->data.s32);
+ else
+ return tag_init_s32(dest, (s32) a->data.u32 + b->data.s32);
case TAG_S64:
- return tag_init_s64(dest, (s64) a->data.u32 + b->data.s64);
+ if (a->data.u32 > S64_MAX - b->data.s64) {
+ integer_init_u32(&tmp, a->data.u32);
+ integer_init_s64(&tmp2, b->data.s64);
+ tag_init_integer_zero(dest);
+ integer_add(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ }
+ else
+ return tag_init_s64(dest, (s64) a->data.u32 + b->data.s64);
case TAG_U8:
- return tag_init_u32(dest, a->data.u32 + (u32) b->data.u8);
+ if (a->data.u32 > U32_MAX - b->data.u8)
+ return tag_init_u64(dest, (u64) a->data.u32 + (u64) b->data.u8);
+ else
+ return tag_init_u32(dest, a->data.u32 + (u32) b->data.u8);
case TAG_U16:
- return tag_init_u32(dest, a->data.u32 + (u32) b->data.u16);
+ if (a->data.u32 > U32_MAX - b->data.u16)
+ return tag_init_u64(dest, (u64) a->data.u32 + (u64) b->data.u16);
+ else
+ return tag_init_u32(dest, a->data.u32 + (u32) b->data.u16);
case TAG_U32:
- return tag_init_u32(dest, a->data.u32 + b->data.u32);
+ if (a->data.u32 > U32_MAX - b->data.u32)
+ return tag_init_u64(dest, (u64) a->data.u32 + (u64) b->data.u32);
+ else
+ return tag_init_u32(dest, a->data.u32 + b->data.u32);
case TAG_U64:
- return tag_init_u64(dest, (u64) a->data.u32 + b->data.u64);
+ if (a->data.u32 > U64_MAX - b->data.u64) {
+ integer_init_u32(&tmp, a->data.u32);
+ integer_init_u64(&tmp2, b->data.u64);
+ tag_init_integer_zero(dest);
+ integer_add(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ }
+ else
+ return tag_init_u64(dest, (u64) a->data.u32 + b->data.u64);
default:
goto ko;
}
@@ -909,6 +947,7 @@ void tag_delete (s_tag *tag)
s_tag * tag_div (const s_tag *a, const s_tag *b, s_tag *dest)
{
s_integer tmp;
+ s_integer tmp2;
assert(a);
assert(b);
assert(dest);
@@ -1219,13 +1258,14 @@ s_tag * tag_div (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
return dest;
case TAG_S8:
- return tag_init_s16(dest, (s16) a->data.u16 / (s16) b->data.s8);
+ return tag_init_s32(dest, (s32) a->data.u16 / (s32) b->data.s8);
case TAG_S16:
- return tag_init_s16(dest, (s16) a->data.u16 / b->data.s16);
+ return tag_init_s32(dest, (s32) a->data.u16 / (s32) b->data.s16);
case TAG_S32:
return tag_init_s32(dest, (s32) a->data.u16 / b->data.s32);
case TAG_S64:
- return tag_init_s64(dest, (s64) a->data.u16 / b->data.s64);
+ return tag_init_s32(dest, (s32) ((s64) a->data.u16 /
+ b->data.s64));
case TAG_U8:
return tag_init_u16(dest, a->data.u16 / (u16) b->data.u8);
case TAG_U16:
@@ -1250,11 +1290,11 @@ s_tag * tag_div (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
return dest;
case TAG_S8:
- return tag_init_s32(dest, (s32) a->data.u32 / (s32) b->data.s8);
+ return tag_init_s64(dest, (s64) a->data.u32 / (s64) b->data.s8);
case TAG_S16:
- return tag_init_s32(dest, (s32) a->data.u32 / (s32) b->data.s16);
+ return tag_init_s64(dest, (s64) a->data.u32 / (s64) b->data.s16);
case TAG_S32:
- return tag_init_s32(dest, (s32) a->data.u32 / b->data.s32);
+ return tag_init_s64(dest, (s64) a->data.u32 / (s64) b->data.s32);
case TAG_S64:
return tag_init_s64(dest, (s64) a->data.u32 / b->data.s64);
case TAG_U8:
@@ -1281,13 +1321,55 @@ s_tag * tag_div (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
return dest;
case TAG_S8:
- return tag_init_s64(dest, (s64) a->data.u64 / (s64) b->data.s8);
+ if (a->data.u64 > S64_MAX) {
+ integer_init_u64(&tmp, a->data.u64);
+ integer_init_s32(&tmp2, (s32) b->data.s8);
+ tag_init_integer_zero(dest);
+ integer_div(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ }
+ else
+ return tag_init_s64(dest, (s64) a->data.u64 / (s64) b->data.s8);
case TAG_S16:
- return tag_init_s64(dest, (s64) a->data.u64 / (s64) b->data.s16);
+ if (a->data.u64 > S64_MAX) {
+ integer_init_u64(&tmp, a->data.u64);
+ integer_init_s32(&tmp2, (s32) b->data.s16);
+ tag_init_integer_zero(dest);
+ integer_div(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ }
+ else
+ return tag_init_s64(dest, (s64) a->data.u64 /
+ (s64) b->data.s16);
case TAG_S32:
- return tag_init_s64(dest, (s64) a->data.u64 / (s64) b->data.s32);
+ if (a->data.u64 > S64_MAX) {
+ integer_init_u64(&tmp, a->data.u64);
+ integer_init_s32(&tmp2, b->data.s32);
+ tag_init_integer_zero(dest);
+ integer_div(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ }
+ else
+ return tag_init_s64(dest, (s64) a->data.u64 /
+ (s64) b->data.s32);
case TAG_S64:
- return tag_init_s64(dest, (s64) a->data.u64 / b->data.s64);
+ if (a->data.u64 > S64_MAX) {
+ integer_init_u64(&tmp, a->data.u64);
+ integer_init_s64(&tmp2, b->data.s64);
+ tag_init_integer_zero(dest);
+ integer_div(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
+ }
+ else
+ return tag_init_s64(dest, (s64) a->data.u64 / b->data.s64);
case TAG_U8:
return tag_init_u64(dest, a->data.u64 / (u64) b->data.u8);
case TAG_U16:
@@ -1959,11 +2041,11 @@ s_tag * tag_mul (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp2);
return dest;
case TAG_U8:
- return tag_init_s16(dest, (s16) a->data.s8 * (s16) b->data.s8);
+ return tag_init_s16(dest, (s16) a->data.s8 * (s16) b->data.u8);
case TAG_U16:
return tag_init_s32(dest, (s32) a->data.s8 * (s32) b->data.u16);
case TAG_U32:
- return tag_init_s32(dest, (s64) a->data.s8 * (s64) b->data.u32);
+ return tag_init_s64(dest, (s64) a->data.s8 * (s64) b->data.u32);
case TAG_U64:
integer_init_s32(&tmp, (s32) a->data.s8);
integer_init_u64(&tmp2, (s64) b->data.u64);
@@ -2452,6 +2534,7 @@ s_tag * tag_str_1 (s_tag *tag, s8 *free, const s8 *p)
s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
{
s_integer tmp;
+ s_integer tmp2;
assert(a);
assert(b);
assert(dest);
@@ -2589,27 +2672,39 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
case TAG_F64:
return tag_init_f64(dest, a->data.s8 - b->data.f64);
case TAG_INTEGER:
- integer_init_s32(&tmp, a->data.s8);
+ integer_init_s8(&tmp, a->data.s8);
integer_sub(&tmp, &b->data.integer, &tmp);
tag_init_integer(dest, &tmp);
integer_clean(&tmp);
return dest;
case TAG_S8:
- return tag_init_s8(dest, a->data.s8 - b->data.s8);
+ return tag_init_s16(dest, (s16) a->data.s8 - (s16) b->data.s8);
case TAG_S16:
- return tag_init_s16(dest, a->data.s8 - b->data.s16);
+ return tag_init_s32(dest, (s32) a->data.s8 - (s32) b->data.s16);
case TAG_S32:
- return tag_init_s32(dest, a->data.s8 - b->data.s32);
+ return tag_init_s64(dest, (s64) a->data.s8 - (s64) b->data.s32);
case TAG_S64:
- return tag_init_s64(dest, a->data.s8 - b->data.s64);
+ integer_init_s8(&tmp, a->data.s8);
+ integer_init_s64(&tmp2, b->data.s64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U8:
- return tag_init_s8(dest, a->data.s8 - b->data.u8);
+ return tag_init_s16(dest, (s16) a->data.s8 - (s16) b->data.u8);
case TAG_U16:
- return tag_init_s16(dest, a->data.s8 - b->data.u16);
+ return tag_init_s32(dest, (s32) a->data.s8 - (s32) b->data.u16);
case TAG_U32:
- return tag_init_s32(dest, a->data.s8 - b->data.u32);
+ return tag_init_s64(dest, (s64) a->data.s8 - (s64) b->data.u32);
case TAG_U64:
- return tag_init_s64(dest, a->data.s8 - b->data.u64);
+ integer_init_s8(&tmp, a->data.s8);
+ integer_init_u64(&tmp2, b->data.u64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}
@@ -2632,15 +2727,27 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
case TAG_S32:
return tag_init_s32(dest, a->data.s16 - b->data.s32);
case TAG_S64:
- return tag_init_s64(dest, a->data.s16 - b->data.s64);
+ integer_init_s16(&tmp, a->data.s16);
+ integer_init_s64(&tmp2, b->data.s64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U8:
- return tag_init_s16(dest, a->data.s16 - b->data.u8);
+ return tag_init_s32(dest, (s32) a->data.s16 - (s32) b->data.u8);
case TAG_U16:
- return tag_init_s16(dest, a->data.s16 - b->data.u16);
+ return tag_init_s32(dest, (s32) a->data.s16 - (s32) b->data.u16);
case TAG_U32:
- return tag_init_s32(dest, a->data.s16 - b->data.u32);
+ return tag_init_s64(dest, (s64) a->data.s16 - (s64) b->data.u32);
case TAG_U64:
- return tag_init_s64(dest, a->data.s16 - b->data.u64);
+ integer_init_s16(&tmp, a->data.s16);
+ integer_init_u64(&tmp2, b->data.u64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}
@@ -2657,21 +2764,33 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
return dest;
case TAG_S8:
- return tag_init_s32(dest, a->data.s32 - b->data.s8);
+ return tag_init_s64(dest, (s64) a->data.s32 - (s64) b->data.s8);
case TAG_S16:
- return tag_init_s32(dest, a->data.s32 - b->data.s16);
+ return tag_init_s64(dest, (s64) a->data.s32 - (s64) b->data.s16);
case TAG_S32:
- return tag_init_s32(dest, a->data.s32 - b->data.s32);
+ return tag_init_s64(dest, (s64) a->data.s32 - (s64) b->data.s32);
case TAG_S64:
- return tag_init_s64(dest, a->data.s32 - b->data.s64);
+ integer_init_s32(&tmp, a->data.s32);
+ integer_init_s64(&tmp2, b->data.s64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U8:
- return tag_init_s32(dest, a->data.s32 - b->data.u8);
+ return tag_init_s64(dest, (s64) a->data.s32 - (s64) b->data.u8);
case TAG_U16:
- return tag_init_s32(dest, a->data.s32 - b->data.u16);
+ return tag_init_s64(dest, (s64) a->data.s32 - (s64) b->data.u16);
case TAG_U32:
- return tag_init_s32(dest, a->data.s32 - b->data.u32);
+ return tag_init_s64(dest, (s64) a->data.s32 - (s64) b->data.u32);
case TAG_U64:
- return tag_init_s64(dest, a->data.s32 - b->data.u64);
+ integer_init_s32(&tmp, a->data.s32);
+ integer_init_u64(&tmp2, b->data.u64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}
@@ -2688,21 +2807,69 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
return dest;
case TAG_S8:
- return tag_init_s64(dest, a->data.s64 - b->data.s8);
+ integer_init_s64(&tmp, a->data.s64);
+ integer_init_s8(&tmp2, b->data.s8);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_S16:
- return tag_init_s64(dest, a->data.s64 - b->data.s16);
+ integer_init_s64(&tmp, a->data.s64);
+ integer_init_s16(&tmp2, b->data.s16);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_S32:
- return tag_init_s64(dest, a->data.s64 - b->data.s32);
+ integer_init_s64(&tmp, a->data.s64);
+ integer_init_s32(&tmp2, b->data.s32);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_S64:
- return tag_init_s64(dest, a->data.s64 - b->data.s64);
+ integer_init_s64(&tmp, a->data.s64);
+ integer_init_s64(&tmp2, b->data.s64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U8:
- return tag_init_s64(dest, a->data.s64 - b->data.u8);
+ integer_init_s64(&tmp, a->data.s64);
+ integer_init_u8(&tmp2, b->data.u8);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U16:
- return tag_init_s64(dest, a->data.s64 - b->data.u16);
+ integer_init_s64(&tmp, a->data.s64);
+ integer_init_u16(&tmp2, b->data.u16);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U32:
- return tag_init_s64(dest, a->data.s64 - b->data.u32);
+ integer_init_s64(&tmp, a->data.s64);
+ integer_init_u32(&tmp2, b->data.u32);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U64:
- return tag_init_s64(dest, a->data.s64 - b->data.u64);
+ integer_init_s64(&tmp, a->data.s64);
+ integer_init_u64(&tmp2, b->data.u64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}
@@ -2719,21 +2886,33 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
return dest;
case TAG_S8:
- return tag_init_s8(dest, a->data.u8 - b->data.s8);
+ return tag_init_s16(dest, (s16) a->data.u8 - (s16) b->data.s8);
case TAG_S16:
- return tag_init_s16(dest, a->data.u8 - b->data.s16);
+ return tag_init_s32(dest, (s32) a->data.u8 - (s32) b->data.s16);
case TAG_S32:
- return tag_init_s32(dest, a->data.u8 - b->data.s32);
+ return tag_init_s64(dest, (s64) a->data.u8 - (s64) b->data.s32);
case TAG_S64:
- return tag_init_s64(dest, a->data.u8 - b->data.s64);
+ integer_init_u8(&tmp, a->data.u8);
+ integer_init_s64(&tmp2, b->data.s64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U8:
- return tag_init_s8(dest, a->data.u8 - b->data.u8);
+ return tag_init_s16(dest, (s16) a->data.u8 - (s16) b->data.u8);
case TAG_U16:
- return tag_init_s16(dest, a->data.u8 - b->data.u16);
+ return tag_init_s32(dest, (s32) a->data.u8 - (s32) b->data.u16);
case TAG_U32:
- return tag_init_s32(dest, a->data.u8 - b->data.u32);
+ return tag_init_s64(dest, (s64) a->data.u8 - (s64) b->data.u32);
case TAG_U64:
- return tag_init_s64(dest, a->data.u8 - b->data.u64);
+ integer_init_u8(&tmp, a->data.u8);
+ integer_init_u64(&tmp2, b->data.u64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}
@@ -2750,21 +2929,33 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
return dest;
case TAG_S8:
- return tag_init_s16(dest, a->data.u16 - b->data.s8);
+ return tag_init_s32(dest, (s32) a->data.u16 - (s32) b->data.s8);
case TAG_S16:
- return tag_init_s16(dest, a->data.u16 - b->data.s16);
+ return tag_init_s32(dest, (s32) a->data.u16 - (s32) b->data.s16);
case TAG_S32:
- return tag_init_s32(dest, a->data.u16 - b->data.s32);
+ return tag_init_s64(dest, (s64) a->data.u16 - (s64) b->data.s32);
case TAG_S64:
- return tag_init_s64(dest, a->data.u16 - b->data.s64);
+ integer_init_u32(&tmp, (u32) a->data.u16);
+ integer_init_s64(&tmp2, b->data.s64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U8:
- return tag_init_s16(dest, a->data.u16 - b->data.u8);
+ return tag_init_s32(dest, (s32) a->data.u16 - (s32) b->data.u8);
case TAG_U16:
- return tag_init_s16(dest, a->data.u16 - b->data.u16);
+ return tag_init_s32(dest, (s32) a->data.u16 - (s32) b->data.u16);
case TAG_U32:
- return tag_init_s32(dest, a->data.u16 - b->data.u32);
+ return tag_init_s64(dest, (s64) a->data.u16 - (s64) b->data.u32);
case TAG_U64:
- return tag_init_s64(dest, a->data.u16 - b->data.u64);
+ integer_init_u32(&tmp, (u32) a->data.u16);
+ integer_init_u64(&tmp2, b->data.u64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}
@@ -2781,21 +2972,33 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
return dest;
case TAG_S8:
- return tag_init_s32(dest, a->data.u32 - b->data.s8);
+ return tag_init_s64(dest, (s64) a->data.u32 - (s64) b->data.s8);
case TAG_S16:
- return tag_init_s32(dest, a->data.u32 - b->data.s16);
+ return tag_init_s64(dest, (s64) a->data.u32 - (s64) b->data.s16);
case TAG_S32:
- return tag_init_s32(dest, a->data.u32 - b->data.s32);
+ return tag_init_s64(dest, (s64) a->data.u32 - (s64) b->data.s32);
case TAG_S64:
- return tag_init_s64(dest, a->data.u32 - b->data.s64);
+ integer_init_u32(&tmp, a->data.u32);
+ integer_init_s64(&tmp2, b->data.s64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U8:
- return tag_init_s32(dest, a->data.u32 - b->data.u8);
+ return tag_init_s64(dest, (s64) a->data.u32 - (s64) b->data.u8);
case TAG_U16:
- return tag_init_s32(dest, a->data.u32 - b->data.u16);
+ return tag_init_s64(dest, (s64) a->data.u32 - (s64) b->data.u16);
case TAG_U32:
- return tag_init_s32(dest, a->data.u32 - b->data.u32);
+ return tag_init_s64(dest, (s64) a->data.u32 - (s64) b->data.u32);
case TAG_U64:
- return tag_init_s64(dest, a->data.u32 - b->data.u64);
+ integer_init_u32(&tmp, a->data.u32);
+ integer_init_u64(&tmp2, b->data.u64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}
@@ -2812,21 +3015,69 @@ s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest)
integer_clean(&tmp);
return dest;
case TAG_S8:
- return tag_init_s64(dest, a->data.u64 - b->data.s8);
+ integer_init_u64(&tmp, a->data.u64);
+ integer_init_s32(&tmp2, (s32) b->data.s8);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_S16:
- return tag_init_s64(dest, a->data.u64 - b->data.s16);
+ integer_init_u64(&tmp, a->data.u64);
+ integer_init_s32(&tmp2, (s32) b->data.s16);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_S32:
- return tag_init_s64(dest, a->data.u64 - b->data.s32);
+ integer_init_u64(&tmp, a->data.u64);
+ integer_init_s32(&tmp2, b->data.s32);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_S64:
- return tag_init_s64(dest, a->data.u64 - b->data.s64);
+ integer_init_u64(&tmp, a->data.u64);
+ integer_init_s64(&tmp2, b->data.s64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U8:
- return tag_init_s64(dest, a->data.u64 - b->data.u8);
+ integer_init_u64(&tmp, a->data.u64);
+ integer_init_u32(&tmp2, (u32) b->data.u8);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U16:
- return tag_init_s64(dest, a->data.u64 - b->data.u16);
+ integer_init_u64(&tmp, a->data.u64);
+ integer_init_u32(&tmp2, (u32) b->data.u16);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U32:
- return tag_init_s64(dest, a->data.u64 - b->data.u32);
+ integer_init_u64(&tmp, a->data.u64);
+ integer_init_u32(&tmp2, b->data.u32);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
case TAG_U64:
- return tag_init_s64(dest, a->data.u64 - b->data.u64);
+ integer_init_u64(&tmp, a->data.u64);
+ integer_init_u64(&tmp2, b->data.u64);
+ tag_init_integer_zero(dest);
+ integer_sub(&tmp, &tmp2, &dest->data.integer);
+ integer_clean(&tmp);
+ integer_clean(&tmp2);
+ return dest;
default:
goto ko;
}