aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2022-01-05 15:05:29 -0800
committerMichael Forney <mforney@mforney.org>2022-01-22 11:36:12 -0800
commitb29fafbf175df9f1d8064342c479476005b3a90e (patch)
tree073516ca8c48f5672a2b73c822a96ddfb6890fe0
parent8e5145949ba477fd49f1e541b8ed1341d4c3bb69 (diff)
eval: Simplify sign/zero extension
-rw-r--r--eval.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/eval.c b/eval.c
index de08a1f..94e873b 100644
--- a/eval.c
+++ b/eval.c
@@ -10,20 +10,18 @@ static void
cast(struct expr *expr)
{
unsigned size;
+ uint64_t m;
size = expr->type->size;
- if (expr->type->prop & PROPFLOAT)
- size |= F;
- else if (expr->type->prop & PROPINT && expr->type->u.basic.issigned)
- size |= S;
- switch (size) {
- case 1: expr->u.constant.u = (uint8_t)expr->u.constant.u; break;
- case 1|S: expr->u.constant.u = (expr->u.constant.u & UINT8_MAX ^ INT8_MIN) - INT8_MIN; break;
- case 2: expr->u.constant.u = (uint16_t)expr->u.constant.u; break;
- case 2|S: expr->u.constant.u = (expr->u.constant.u & UINT16_MAX ^ INT16_MIN) - INT16_MIN; break;
- case 4: expr->u.constant.u = (uint32_t)expr->u.constant.u; break;
- case 4|S: expr->u.constant.u = (expr->u.constant.u & UINT32_MAX ^ INT32_MIN) - INT32_MIN; break;
- case 4|F: expr->u.constant.f = (float)expr->u.constant.f; break;
+ if (expr->type->prop & PROPFLOAT) {
+ if (size == 4)
+ expr->u.constant.f = (float)expr->u.constant.f;
+ } else if (expr->type->prop & PROPINT) {
+ expr->u.constant.u &= UINT64_MAX >> (8 - size) * 8;
+ if (expr->type->u.basic.issigned) {
+ m = 1ull << size * 8 - 1;
+ expr->u.constant.u = (expr->u.constant.u ^ m) - m;
+ }
}
}