1*1f5207b7SJohn Levon /* 2*1f5207b7SJohn Levon * sparse/expand.c 3*1f5207b7SJohn Levon * 4*1f5207b7SJohn Levon * Copyright (C) 2003 Transmeta Corp. 5*1f5207b7SJohn Levon * 2003-2004 Linus Torvalds 6*1f5207b7SJohn Levon * 7*1f5207b7SJohn Levon * Permission is hereby granted, free of charge, to any person obtaining a copy 8*1f5207b7SJohn Levon * of this software and associated documentation files (the "Software"), to deal 9*1f5207b7SJohn Levon * in the Software without restriction, including without limitation the rights 10*1f5207b7SJohn Levon * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11*1f5207b7SJohn Levon * copies of the Software, and to permit persons to whom the Software is 12*1f5207b7SJohn Levon * furnished to do so, subject to the following conditions: 13*1f5207b7SJohn Levon * 14*1f5207b7SJohn Levon * The above copyright notice and this permission notice shall be included in 15*1f5207b7SJohn Levon * all copies or substantial portions of the Software. 16*1f5207b7SJohn Levon * 17*1f5207b7SJohn Levon * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18*1f5207b7SJohn Levon * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19*1f5207b7SJohn Levon * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20*1f5207b7SJohn Levon * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21*1f5207b7SJohn Levon * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22*1f5207b7SJohn Levon * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23*1f5207b7SJohn Levon * THE SOFTWARE. 24*1f5207b7SJohn Levon * 25*1f5207b7SJohn Levon * expand constant expressions. 26*1f5207b7SJohn Levon */ 27*1f5207b7SJohn Levon #include <stdlib.h> 28*1f5207b7SJohn Levon #include <stdarg.h> 29*1f5207b7SJohn Levon #include <stddef.h> 30*1f5207b7SJohn Levon #include <stdio.h> 31*1f5207b7SJohn Levon #include <string.h> 32*1f5207b7SJohn Levon #include <ctype.h> 33*1f5207b7SJohn Levon #include <unistd.h> 34*1f5207b7SJohn Levon #include <fcntl.h> 35*1f5207b7SJohn Levon #include <limits.h> 36*1f5207b7SJohn Levon 37*1f5207b7SJohn Levon #include "lib.h" 38*1f5207b7SJohn Levon #include "allocate.h" 39*1f5207b7SJohn Levon #include "parse.h" 40*1f5207b7SJohn Levon #include "token.h" 41*1f5207b7SJohn Levon #include "symbol.h" 42*1f5207b7SJohn Levon #include "target.h" 43*1f5207b7SJohn Levon #include "expression.h" 44*1f5207b7SJohn Levon #include "expand.h" 45*1f5207b7SJohn Levon 46*1f5207b7SJohn Levon 47*1f5207b7SJohn Levon static int expand_expression(struct expression *); 48*1f5207b7SJohn Levon static int expand_statement(struct statement *); 49*1f5207b7SJohn Levon static int conservative; 50*1f5207b7SJohn Levon 51*1f5207b7SJohn Levon static int expand_symbol_expression(struct expression *expr) 52*1f5207b7SJohn Levon { 53*1f5207b7SJohn Levon struct symbol *sym = expr->symbol; 54*1f5207b7SJohn Levon 55*1f5207b7SJohn Levon if (sym == &zero_int) { 56*1f5207b7SJohn Levon if (Wundef) 57*1f5207b7SJohn Levon warning(expr->pos, "undefined preprocessor identifier '%s'", show_ident(expr->symbol_name)); 58*1f5207b7SJohn Levon expr->type = EXPR_VALUE; 59*1f5207b7SJohn Levon expr->value = 0; 60*1f5207b7SJohn Levon expr->taint = 0; 61*1f5207b7SJohn Levon return 0; 62*1f5207b7SJohn Levon } 63*1f5207b7SJohn Levon /* The cost of a symbol expression is lower for on-stack symbols */ 64*1f5207b7SJohn Levon return (sym->ctype.modifiers & (MOD_STATIC | MOD_EXTERN)) ? 2 : 1; 65*1f5207b7SJohn Levon } 66*1f5207b7SJohn Levon 67*1f5207b7SJohn Levon static long long get_longlong(struct expression *expr) 68*1f5207b7SJohn Levon { 69*1f5207b7SJohn Levon int no_expand = expr->ctype->ctype.modifiers & MOD_UNSIGNED; 70*1f5207b7SJohn Levon long long mask = 1ULL << (expr->ctype->bit_size - 1); 71*1f5207b7SJohn Levon long long value = expr->value; 72*1f5207b7SJohn Levon long long ormask, andmask; 73*1f5207b7SJohn Levon 74*1f5207b7SJohn Levon if (!(value & mask)) 75*1f5207b7SJohn Levon no_expand = 1; 76*1f5207b7SJohn Levon andmask = mask | (mask-1); 77*1f5207b7SJohn Levon ormask = ~andmask; 78*1f5207b7SJohn Levon if (no_expand) 79*1f5207b7SJohn Levon ormask = 0; 80*1f5207b7SJohn Levon return (value & andmask) | ormask; 81*1f5207b7SJohn Levon } 82*1f5207b7SJohn Levon 83*1f5207b7SJohn Levon void cast_value(struct expression *expr, struct symbol *newtype, 84*1f5207b7SJohn Levon struct expression *old, struct symbol *oldtype) 85*1f5207b7SJohn Levon { 86*1f5207b7SJohn Levon int old_size = oldtype->bit_size; 87*1f5207b7SJohn Levon int new_size = newtype->bit_size; 88*1f5207b7SJohn Levon long long value, mask, signmask; 89*1f5207b7SJohn Levon long long oldmask, oldsignmask, dropped; 90*1f5207b7SJohn Levon 91*1f5207b7SJohn Levon if (is_float_type(newtype) || is_float_type(oldtype)) 92*1f5207b7SJohn Levon goto Float; 93*1f5207b7SJohn Levon 94*1f5207b7SJohn Levon // For pointers and integers, we can just move the value around 95*1f5207b7SJohn Levon expr->type = EXPR_VALUE; 96*1f5207b7SJohn Levon expr->taint = old->taint; 97*1f5207b7SJohn Levon if (old_size == new_size) { 98*1f5207b7SJohn Levon expr->value = old->value; 99*1f5207b7SJohn Levon return; 100*1f5207b7SJohn Levon } 101*1f5207b7SJohn Levon 102*1f5207b7SJohn Levon // expand it to the full "long long" value 103*1f5207b7SJohn Levon value = get_longlong(old); 104*1f5207b7SJohn Levon 105*1f5207b7SJohn Levon Int: 106*1f5207b7SJohn Levon // _Bool requires a zero test rather than truncation. 107*1f5207b7SJohn Levon if (is_bool_type(newtype)) { 108*1f5207b7SJohn Levon expr->value = !!value; 109*1f5207b7SJohn Levon if (!conservative && value != 0 && value != 1) 110*1f5207b7SJohn Levon warning(old->pos, "odd constant _Bool cast (%llx becomes 1)", value); 111*1f5207b7SJohn Levon return; 112*1f5207b7SJohn Levon } 113*1f5207b7SJohn Levon 114*1f5207b7SJohn Levon // Truncate it to the new size 115*1f5207b7SJohn Levon signmask = 1ULL << (new_size-1); 116*1f5207b7SJohn Levon mask = signmask | (signmask-1); 117*1f5207b7SJohn Levon expr->value = value & mask; 118*1f5207b7SJohn Levon 119*1f5207b7SJohn Levon // Stop here unless checking for truncation 120*1f5207b7SJohn Levon if (!Wcast_truncate || conservative) 121*1f5207b7SJohn Levon return; 122*1f5207b7SJohn Levon 123*1f5207b7SJohn Levon // Check if we dropped any bits.. 124*1f5207b7SJohn Levon oldsignmask = 1ULL << (old_size-1); 125*1f5207b7SJohn Levon oldmask = oldsignmask | (oldsignmask-1); 126*1f5207b7SJohn Levon dropped = oldmask & ~mask; 127*1f5207b7SJohn Levon 128*1f5207b7SJohn Levon // OK if the bits were (and still are) purely sign bits 129*1f5207b7SJohn Levon if (value & dropped) { 130*1f5207b7SJohn Levon if (!(value & oldsignmask) || !(value & signmask) || (value & dropped) != dropped) 131*1f5207b7SJohn Levon warning(old->pos, "cast truncates bits from constant value (%llx becomes %llx)", 132*1f5207b7SJohn Levon value & oldmask, 133*1f5207b7SJohn Levon value & mask); 134*1f5207b7SJohn Levon } 135*1f5207b7SJohn Levon return; 136*1f5207b7SJohn Levon 137*1f5207b7SJohn Levon Float: 138*1f5207b7SJohn Levon if (!is_float_type(newtype)) { 139*1f5207b7SJohn Levon value = (long long)old->fvalue; 140*1f5207b7SJohn Levon expr->type = EXPR_VALUE; 141*1f5207b7SJohn Levon expr->taint = 0; 142*1f5207b7SJohn Levon goto Int; 143*1f5207b7SJohn Levon } 144*1f5207b7SJohn Levon 145*1f5207b7SJohn Levon if (!is_float_type(oldtype)) 146*1f5207b7SJohn Levon expr->fvalue = (long double)get_longlong(old); 147*1f5207b7SJohn Levon else 148*1f5207b7SJohn Levon expr->fvalue = old->fvalue; 149*1f5207b7SJohn Levon 150*1f5207b7SJohn Levon if (!(newtype->ctype.modifiers & MOD_LONGLONG) && \ 151*1f5207b7SJohn Levon !(newtype->ctype.modifiers & MOD_LONGLONGLONG)) { 152*1f5207b7SJohn Levon if ((newtype->ctype.modifiers & MOD_LONG)) 153*1f5207b7SJohn Levon expr->fvalue = (double)expr->fvalue; 154*1f5207b7SJohn Levon else 155*1f5207b7SJohn Levon expr->fvalue = (float)expr->fvalue; 156*1f5207b7SJohn Levon } 157*1f5207b7SJohn Levon expr->type = EXPR_FVALUE; 158*1f5207b7SJohn Levon } 159*1f5207b7SJohn Levon 160*1f5207b7SJohn Levon static int check_shift_count(struct expression *expr, struct symbol *ctype, unsigned int count) 161*1f5207b7SJohn Levon { 162*1f5207b7SJohn Levon warning(expr->pos, "shift too big (%u) for type %s", count, show_typename(ctype)); 163*1f5207b7SJohn Levon count &= ctype->bit_size-1; 164*1f5207b7SJohn Levon return count; 165*1f5207b7SJohn Levon } 166*1f5207b7SJohn Levon 167*1f5207b7SJohn Levon /* 168*1f5207b7SJohn Levon * CAREFUL! We need to get the size and sign of the 169*1f5207b7SJohn Levon * result right! 170*1f5207b7SJohn Levon */ 171*1f5207b7SJohn Levon #define CONVERT(op,s) (((op)<<1)+(s)) 172*1f5207b7SJohn Levon #define SIGNED(op) CONVERT(op, 1) 173*1f5207b7SJohn Levon #define UNSIGNED(op) CONVERT(op, 0) 174*1f5207b7SJohn Levon static int simplify_int_binop(struct expression *expr, struct symbol *ctype) 175*1f5207b7SJohn Levon { 176*1f5207b7SJohn Levon struct expression *left = expr->left, *right = expr->right; 177*1f5207b7SJohn Levon unsigned long long v, l, r, mask; 178*1f5207b7SJohn Levon signed long long sl, sr; 179*1f5207b7SJohn Levon int is_signed; 180*1f5207b7SJohn Levon 181*1f5207b7SJohn Levon if (right->type != EXPR_VALUE) 182*1f5207b7SJohn Levon return 0; 183*1f5207b7SJohn Levon r = right->value; 184*1f5207b7SJohn Levon if (expr->op == SPECIAL_LEFTSHIFT || expr->op == SPECIAL_RIGHTSHIFT) { 185*1f5207b7SJohn Levon if (r >= ctype->bit_size) { 186*1f5207b7SJohn Levon if (conservative) 187*1f5207b7SJohn Levon return 0; 188*1f5207b7SJohn Levon r = check_shift_count(expr, ctype, r); 189*1f5207b7SJohn Levon right->value = r; 190*1f5207b7SJohn Levon } 191*1f5207b7SJohn Levon } 192*1f5207b7SJohn Levon if (left->type != EXPR_VALUE) 193*1f5207b7SJohn Levon return 0; 194*1f5207b7SJohn Levon l = left->value; r = right->value; 195*1f5207b7SJohn Levon is_signed = !(ctype->ctype.modifiers & MOD_UNSIGNED); 196*1f5207b7SJohn Levon mask = 1ULL << (ctype->bit_size-1); 197*1f5207b7SJohn Levon sl = l; sr = r; 198*1f5207b7SJohn Levon if (is_signed && (sl & mask)) 199*1f5207b7SJohn Levon sl |= ~(mask-1); 200*1f5207b7SJohn Levon if (is_signed && (sr & mask)) 201*1f5207b7SJohn Levon sr |= ~(mask-1); 202*1f5207b7SJohn Levon 203*1f5207b7SJohn Levon switch (CONVERT(expr->op,is_signed)) { 204*1f5207b7SJohn Levon case SIGNED('+'): 205*1f5207b7SJohn Levon case UNSIGNED('+'): 206*1f5207b7SJohn Levon v = l + r; 207*1f5207b7SJohn Levon break; 208*1f5207b7SJohn Levon 209*1f5207b7SJohn Levon case SIGNED('-'): 210*1f5207b7SJohn Levon case UNSIGNED('-'): 211*1f5207b7SJohn Levon v = l - r; 212*1f5207b7SJohn Levon break; 213*1f5207b7SJohn Levon 214*1f5207b7SJohn Levon case SIGNED('&'): 215*1f5207b7SJohn Levon case UNSIGNED('&'): 216*1f5207b7SJohn Levon v = l & r; 217*1f5207b7SJohn Levon break; 218*1f5207b7SJohn Levon 219*1f5207b7SJohn Levon case SIGNED('|'): 220*1f5207b7SJohn Levon case UNSIGNED('|'): 221*1f5207b7SJohn Levon v = l | r; 222*1f5207b7SJohn Levon break; 223*1f5207b7SJohn Levon 224*1f5207b7SJohn Levon case SIGNED('^'): 225*1f5207b7SJohn Levon case UNSIGNED('^'): 226*1f5207b7SJohn Levon v = l ^ r; 227*1f5207b7SJohn Levon break; 228*1f5207b7SJohn Levon 229*1f5207b7SJohn Levon case SIGNED('*'): 230*1f5207b7SJohn Levon v = sl * sr; 231*1f5207b7SJohn Levon break; 232*1f5207b7SJohn Levon 233*1f5207b7SJohn Levon case UNSIGNED('*'): 234*1f5207b7SJohn Levon v = l * r; 235*1f5207b7SJohn Levon break; 236*1f5207b7SJohn Levon 237*1f5207b7SJohn Levon case SIGNED('/'): 238*1f5207b7SJohn Levon if (!r) 239*1f5207b7SJohn Levon goto Div; 240*1f5207b7SJohn Levon if (l == mask && sr == -1) 241*1f5207b7SJohn Levon goto Overflow; 242*1f5207b7SJohn Levon v = sl / sr; 243*1f5207b7SJohn Levon break; 244*1f5207b7SJohn Levon 245*1f5207b7SJohn Levon case UNSIGNED('/'): 246*1f5207b7SJohn Levon if (!r) goto Div; 247*1f5207b7SJohn Levon v = l / r; 248*1f5207b7SJohn Levon break; 249*1f5207b7SJohn Levon 250*1f5207b7SJohn Levon case SIGNED('%'): 251*1f5207b7SJohn Levon if (!r) 252*1f5207b7SJohn Levon goto Div; 253*1f5207b7SJohn Levon if (l == mask && sr == -1) 254*1f5207b7SJohn Levon goto Overflow; 255*1f5207b7SJohn Levon v = sl % sr; 256*1f5207b7SJohn Levon break; 257*1f5207b7SJohn Levon 258*1f5207b7SJohn Levon case UNSIGNED('%'): 259*1f5207b7SJohn Levon if (!r) goto Div; 260*1f5207b7SJohn Levon v = l % r; 261*1f5207b7SJohn Levon break; 262*1f5207b7SJohn Levon 263*1f5207b7SJohn Levon case SIGNED(SPECIAL_LEFTSHIFT): 264*1f5207b7SJohn Levon case UNSIGNED(SPECIAL_LEFTSHIFT): 265*1f5207b7SJohn Levon v = l << r; 266*1f5207b7SJohn Levon break; 267*1f5207b7SJohn Levon 268*1f5207b7SJohn Levon case SIGNED(SPECIAL_RIGHTSHIFT): 269*1f5207b7SJohn Levon v = sl >> r; 270*1f5207b7SJohn Levon break; 271*1f5207b7SJohn Levon 272*1f5207b7SJohn Levon case UNSIGNED(SPECIAL_RIGHTSHIFT): 273*1f5207b7SJohn Levon v = l >> r; 274*1f5207b7SJohn Levon break; 275*1f5207b7SJohn Levon 276*1f5207b7SJohn Levon default: 277*1f5207b7SJohn Levon return 0; 278*1f5207b7SJohn Levon } 279*1f5207b7SJohn Levon mask = mask | (mask-1); 280*1f5207b7SJohn Levon expr->value = v & mask; 281*1f5207b7SJohn Levon expr->type = EXPR_VALUE; 282*1f5207b7SJohn Levon expr->taint = left->taint | right->taint; 283*1f5207b7SJohn Levon return 1; 284*1f5207b7SJohn Levon Div: 285*1f5207b7SJohn Levon if (!conservative) 286*1f5207b7SJohn Levon warning(expr->pos, "division by zero"); 287*1f5207b7SJohn Levon return 0; 288*1f5207b7SJohn Levon Overflow: 289*1f5207b7SJohn Levon if (!conservative) 290*1f5207b7SJohn Levon warning(expr->pos, "constant integer operation overflow"); 291*1f5207b7SJohn Levon return 0; 292*1f5207b7SJohn Levon } 293*1f5207b7SJohn Levon 294*1f5207b7SJohn Levon static int simplify_cmp_binop(struct expression *expr, struct symbol *ctype) 295*1f5207b7SJohn Levon { 296*1f5207b7SJohn Levon struct expression *left = expr->left, *right = expr->right; 297*1f5207b7SJohn Levon unsigned long long l, r, mask; 298*1f5207b7SJohn Levon signed long long sl, sr; 299*1f5207b7SJohn Levon 300*1f5207b7SJohn Levon if (left->type != EXPR_VALUE || right->type != EXPR_VALUE) 301*1f5207b7SJohn Levon return 0; 302*1f5207b7SJohn Levon l = left->value; r = right->value; 303*1f5207b7SJohn Levon mask = 1ULL << (ctype->bit_size-1); 304*1f5207b7SJohn Levon sl = l; sr = r; 305*1f5207b7SJohn Levon if (sl & mask) 306*1f5207b7SJohn Levon sl |= ~(mask-1); 307*1f5207b7SJohn Levon if (sr & mask) 308*1f5207b7SJohn Levon sr |= ~(mask-1); 309*1f5207b7SJohn Levon switch (expr->op) { 310*1f5207b7SJohn Levon case '<': expr->value = sl < sr; break; 311*1f5207b7SJohn Levon case '>': expr->value = sl > sr; break; 312*1f5207b7SJohn Levon case SPECIAL_LTE: expr->value = sl <= sr; break; 313*1f5207b7SJohn Levon case SPECIAL_GTE: expr->value = sl >= sr; break; 314*1f5207b7SJohn Levon case SPECIAL_EQUAL: expr->value = l == r; break; 315*1f5207b7SJohn Levon case SPECIAL_NOTEQUAL: expr->value = l != r; break; 316*1f5207b7SJohn Levon case SPECIAL_UNSIGNED_LT:expr->value = l < r; break; 317*1f5207b7SJohn Levon case SPECIAL_UNSIGNED_GT:expr->value = l > r; break; 318*1f5207b7SJohn Levon case SPECIAL_UNSIGNED_LTE:expr->value = l <= r; break; 319*1f5207b7SJohn Levon case SPECIAL_UNSIGNED_GTE:expr->value = l >= r; break; 320*1f5207b7SJohn Levon } 321*1f5207b7SJohn Levon expr->type = EXPR_VALUE; 322*1f5207b7SJohn Levon expr->taint = left->taint | right->taint; 323*1f5207b7SJohn Levon return 1; 324*1f5207b7SJohn Levon } 325*1f5207b7SJohn Levon 326*1f5207b7SJohn Levon static int simplify_float_binop(struct expression *expr) 327*1f5207b7SJohn Levon { 328*1f5207b7SJohn Levon struct expression *left = expr->left, *right = expr->right; 329*1f5207b7SJohn Levon unsigned long mod = expr->ctype->ctype.modifiers; 330*1f5207b7SJohn Levon long double l, r, res; 331*1f5207b7SJohn Levon 332*1f5207b7SJohn Levon if (left->type != EXPR_FVALUE || right->type != EXPR_FVALUE) 333*1f5207b7SJohn Levon return 0; 334*1f5207b7SJohn Levon 335*1f5207b7SJohn Levon l = left->fvalue; 336*1f5207b7SJohn Levon r = right->fvalue; 337*1f5207b7SJohn Levon 338*1f5207b7SJohn Levon if (mod & MOD_LONGLONG) { 339*1f5207b7SJohn Levon switch (expr->op) { 340*1f5207b7SJohn Levon case '+': res = l + r; break; 341*1f5207b7SJohn Levon case '-': res = l - r; break; 342*1f5207b7SJohn Levon case '*': res = l * r; break; 343*1f5207b7SJohn Levon case '/': if (!r) goto Div; 344*1f5207b7SJohn Levon res = l / r; break; 345*1f5207b7SJohn Levon default: return 0; 346*1f5207b7SJohn Levon } 347*1f5207b7SJohn Levon } else if (mod & MOD_LONG) { 348*1f5207b7SJohn Levon switch (expr->op) { 349*1f5207b7SJohn Levon case '+': res = (double) l + (double) r; break; 350*1f5207b7SJohn Levon case '-': res = (double) l - (double) r; break; 351*1f5207b7SJohn Levon case '*': res = (double) l * (double) r; break; 352*1f5207b7SJohn Levon case '/': if (!r) goto Div; 353*1f5207b7SJohn Levon res = (double) l / (double) r; break; 354*1f5207b7SJohn Levon default: return 0; 355*1f5207b7SJohn Levon } 356*1f5207b7SJohn Levon } else { 357*1f5207b7SJohn Levon switch (expr->op) { 358*1f5207b7SJohn Levon case '+': res = (float)l + (float)r; break; 359*1f5207b7SJohn Levon case '-': res = (float)l - (float)r; break; 360*1f5207b7SJohn Levon case '*': res = (float)l * (float)r; break; 361*1f5207b7SJohn Levon case '/': if (!r) goto Div; 362*1f5207b7SJohn Levon res = (float)l / (float)r; break; 363*1f5207b7SJohn Levon default: return 0; 364*1f5207b7SJohn Levon } 365*1f5207b7SJohn Levon } 366*1f5207b7SJohn Levon expr->type = EXPR_FVALUE; 367*1f5207b7SJohn Levon expr->fvalue = res; 368*1f5207b7SJohn Levon return 1; 369*1f5207b7SJohn Levon Div: 370*1f5207b7SJohn Levon if (!conservative) 371*1f5207b7SJohn Levon warning(expr->pos, "division by zero"); 372*1f5207b7SJohn Levon return 0; 373*1f5207b7SJohn Levon } 374*1f5207b7SJohn Levon 375*1f5207b7SJohn Levon static int simplify_float_cmp(struct expression *expr, struct symbol *ctype) 376*1f5207b7SJohn Levon { 377*1f5207b7SJohn Levon struct expression *left = expr->left, *right = expr->right; 378*1f5207b7SJohn Levon long double l, r; 379*1f5207b7SJohn Levon 380*1f5207b7SJohn Levon if (left->type != EXPR_FVALUE || right->type != EXPR_FVALUE) 381*1f5207b7SJohn Levon return 0; 382*1f5207b7SJohn Levon 383*1f5207b7SJohn Levon l = left->fvalue; 384*1f5207b7SJohn Levon r = right->fvalue; 385*1f5207b7SJohn Levon switch (expr->op) { 386*1f5207b7SJohn Levon case '<': expr->value = l < r; break; 387*1f5207b7SJohn Levon case '>': expr->value = l > r; break; 388*1f5207b7SJohn Levon case SPECIAL_LTE: expr->value = l <= r; break; 389*1f5207b7SJohn Levon case SPECIAL_GTE: expr->value = l >= r; break; 390*1f5207b7SJohn Levon case SPECIAL_EQUAL: expr->value = l == r; break; 391*1f5207b7SJohn Levon case SPECIAL_NOTEQUAL: expr->value = l != r; break; 392*1f5207b7SJohn Levon } 393*1f5207b7SJohn Levon expr->type = EXPR_VALUE; 394*1f5207b7SJohn Levon expr->taint = 0; 395*1f5207b7SJohn Levon return 1; 396*1f5207b7SJohn Levon } 397*1f5207b7SJohn Levon 398*1f5207b7SJohn Levon static int expand_binop(struct expression *expr) 399*1f5207b7SJohn Levon { 400*1f5207b7SJohn Levon int cost; 401*1f5207b7SJohn Levon 402*1f5207b7SJohn Levon cost = expand_expression(expr->left); 403*1f5207b7SJohn Levon cost += expand_expression(expr->right); 404*1f5207b7SJohn Levon if (simplify_int_binop(expr, expr->ctype)) 405*1f5207b7SJohn Levon return 0; 406*1f5207b7SJohn Levon if (simplify_float_binop(expr)) 407*1f5207b7SJohn Levon return 0; 408*1f5207b7SJohn Levon return cost + 1; 409*1f5207b7SJohn Levon } 410*1f5207b7SJohn Levon 411*1f5207b7SJohn Levon static int expand_logical(struct expression *expr) 412*1f5207b7SJohn Levon { 413*1f5207b7SJohn Levon struct expression *left = expr->left; 414*1f5207b7SJohn Levon struct expression *right; 415*1f5207b7SJohn Levon int cost, rcost; 416*1f5207b7SJohn Levon 417*1f5207b7SJohn Levon /* Do immediate short-circuiting ... */ 418*1f5207b7SJohn Levon cost = expand_expression(left); 419*1f5207b7SJohn Levon if (left->type == EXPR_VALUE) { 420*1f5207b7SJohn Levon if (expr->op == SPECIAL_LOGICAL_AND) { 421*1f5207b7SJohn Levon if (!left->value) { 422*1f5207b7SJohn Levon expr->type = EXPR_VALUE; 423*1f5207b7SJohn Levon expr->value = 0; 424*1f5207b7SJohn Levon expr->taint = left->taint; 425*1f5207b7SJohn Levon return 0; 426*1f5207b7SJohn Levon } 427*1f5207b7SJohn Levon } else { 428*1f5207b7SJohn Levon if (left->value) { 429*1f5207b7SJohn Levon expr->type = EXPR_VALUE; 430*1f5207b7SJohn Levon expr->value = 1; 431*1f5207b7SJohn Levon expr->taint = left->taint; 432*1f5207b7SJohn Levon return 0; 433*1f5207b7SJohn Levon } 434*1f5207b7SJohn Levon } 435*1f5207b7SJohn Levon } 436*1f5207b7SJohn Levon 437*1f5207b7SJohn Levon right = expr->right; 438*1f5207b7SJohn Levon rcost = expand_expression(right); 439*1f5207b7SJohn Levon if (left->type == EXPR_VALUE && right->type == EXPR_VALUE) { 440*1f5207b7SJohn Levon /* 441*1f5207b7SJohn Levon * We know the left value doesn't matter, since 442*1f5207b7SJohn Levon * otherwise we would have short-circuited it.. 443*1f5207b7SJohn Levon */ 444*1f5207b7SJohn Levon expr->type = EXPR_VALUE; 445*1f5207b7SJohn Levon expr->value = right->value != 0; 446*1f5207b7SJohn Levon expr->taint = left->taint | right->taint; 447*1f5207b7SJohn Levon return 0; 448*1f5207b7SJohn Levon } 449*1f5207b7SJohn Levon 450*1f5207b7SJohn Levon /* 451*1f5207b7SJohn Levon * If the right side is safe and cheaper than a branch, 452*1f5207b7SJohn Levon * just avoid the branch and turn it into a regular binop 453*1f5207b7SJohn Levon * style SAFELOGICAL. 454*1f5207b7SJohn Levon */ 455*1f5207b7SJohn Levon if (rcost < BRANCH_COST) { 456*1f5207b7SJohn Levon expr->type = EXPR_BINOP; 457*1f5207b7SJohn Levon rcost -= BRANCH_COST - 1; 458*1f5207b7SJohn Levon } 459*1f5207b7SJohn Levon 460*1f5207b7SJohn Levon return cost + BRANCH_COST + rcost; 461*1f5207b7SJohn Levon } 462*1f5207b7SJohn Levon 463*1f5207b7SJohn Levon static int expand_comma(struct expression *expr) 464*1f5207b7SJohn Levon { 465*1f5207b7SJohn Levon int cost; 466*1f5207b7SJohn Levon 467*1f5207b7SJohn Levon cost = expand_expression(expr->left); 468*1f5207b7SJohn Levon cost += expand_expression(expr->right); 469*1f5207b7SJohn Levon if (expr->left->type == EXPR_VALUE || expr->left->type == EXPR_FVALUE) { 470*1f5207b7SJohn Levon unsigned flags = expr->flags; 471*1f5207b7SJohn Levon unsigned taint; 472*1f5207b7SJohn Levon taint = expr->left->type == EXPR_VALUE ? expr->left->taint : 0; 473*1f5207b7SJohn Levon *expr = *expr->right; 474*1f5207b7SJohn Levon expr->flags = flags; 475*1f5207b7SJohn Levon if (expr->type == EXPR_VALUE) 476*1f5207b7SJohn Levon expr->taint |= Taint_comma | taint; 477*1f5207b7SJohn Levon } 478*1f5207b7SJohn Levon return cost; 479*1f5207b7SJohn Levon } 480*1f5207b7SJohn Levon 481*1f5207b7SJohn Levon #define MOD_IGN (MOD_VOLATILE | MOD_CONST) 482*1f5207b7SJohn Levon 483*1f5207b7SJohn Levon static int compare_types(int op, struct symbol *left, struct symbol *right) 484*1f5207b7SJohn Levon { 485*1f5207b7SJohn Levon struct ctype c1 = {.base_type = left}; 486*1f5207b7SJohn Levon struct ctype c2 = {.base_type = right}; 487*1f5207b7SJohn Levon switch (op) { 488*1f5207b7SJohn Levon case SPECIAL_EQUAL: 489*1f5207b7SJohn Levon return !type_difference(&c1, &c2, MOD_IGN, MOD_IGN); 490*1f5207b7SJohn Levon case SPECIAL_NOTEQUAL: 491*1f5207b7SJohn Levon return type_difference(&c1, &c2, MOD_IGN, MOD_IGN) != NULL; 492*1f5207b7SJohn Levon case '<': 493*1f5207b7SJohn Levon return left->bit_size < right->bit_size; 494*1f5207b7SJohn Levon case '>': 495*1f5207b7SJohn Levon return left->bit_size > right->bit_size; 496*1f5207b7SJohn Levon case SPECIAL_LTE: 497*1f5207b7SJohn Levon return left->bit_size <= right->bit_size; 498*1f5207b7SJohn Levon case SPECIAL_GTE: 499*1f5207b7SJohn Levon return left->bit_size >= right->bit_size; 500*1f5207b7SJohn Levon } 501*1f5207b7SJohn Levon return 0; 502*1f5207b7SJohn Levon } 503*1f5207b7SJohn Levon 504*1f5207b7SJohn Levon static int expand_compare(struct expression *expr) 505*1f5207b7SJohn Levon { 506*1f5207b7SJohn Levon struct expression *left = expr->left, *right = expr->right; 507*1f5207b7SJohn Levon int cost; 508*1f5207b7SJohn Levon 509*1f5207b7SJohn Levon cost = expand_expression(left); 510*1f5207b7SJohn Levon cost += expand_expression(right); 511*1f5207b7SJohn Levon 512*1f5207b7SJohn Levon if (left && right) { 513*1f5207b7SJohn Levon /* Type comparison? */ 514*1f5207b7SJohn Levon if (left->type == EXPR_TYPE && right->type == EXPR_TYPE) { 515*1f5207b7SJohn Levon int op = expr->op; 516*1f5207b7SJohn Levon expr->type = EXPR_VALUE; 517*1f5207b7SJohn Levon expr->value = compare_types(op, left->symbol, right->symbol); 518*1f5207b7SJohn Levon expr->taint = 0; 519*1f5207b7SJohn Levon return 0; 520*1f5207b7SJohn Levon } 521*1f5207b7SJohn Levon if (simplify_cmp_binop(expr, left->ctype)) 522*1f5207b7SJohn Levon return 0; 523*1f5207b7SJohn Levon if (simplify_float_cmp(expr, left->ctype)) 524*1f5207b7SJohn Levon return 0; 525*1f5207b7SJohn Levon } 526*1f5207b7SJohn Levon return cost + 1; 527*1f5207b7SJohn Levon } 528*1f5207b7SJohn Levon 529*1f5207b7SJohn Levon static int expand_conditional(struct expression *expr) 530*1f5207b7SJohn Levon { 531*1f5207b7SJohn Levon struct expression *cond = expr->conditional; 532*1f5207b7SJohn Levon struct expression *true = expr->cond_true; 533*1f5207b7SJohn Levon struct expression *false = expr->cond_false; 534*1f5207b7SJohn Levon int cost, cond_cost; 535*1f5207b7SJohn Levon 536*1f5207b7SJohn Levon cond_cost = expand_expression(cond); 537*1f5207b7SJohn Levon if (cond->type == EXPR_VALUE) { 538*1f5207b7SJohn Levon unsigned flags = expr->flags; 539*1f5207b7SJohn Levon if (!cond->value) 540*1f5207b7SJohn Levon true = false; 541*1f5207b7SJohn Levon if (!true) 542*1f5207b7SJohn Levon true = cond; 543*1f5207b7SJohn Levon cost = expand_expression(true); 544*1f5207b7SJohn Levon *expr = *true; 545*1f5207b7SJohn Levon expr->flags = flags; 546*1f5207b7SJohn Levon if (expr->type == EXPR_VALUE) 547*1f5207b7SJohn Levon expr->taint |= cond->taint; 548*1f5207b7SJohn Levon return cost; 549*1f5207b7SJohn Levon } 550*1f5207b7SJohn Levon 551*1f5207b7SJohn Levon cost = expand_expression(true); 552*1f5207b7SJohn Levon cost += expand_expression(false); 553*1f5207b7SJohn Levon 554*1f5207b7SJohn Levon if (cost < SELECT_COST) { 555*1f5207b7SJohn Levon expr->type = EXPR_SELECT; 556*1f5207b7SJohn Levon cost -= BRANCH_COST - 1; 557*1f5207b7SJohn Levon } 558*1f5207b7SJohn Levon 559*1f5207b7SJohn Levon return cost + cond_cost + BRANCH_COST; 560*1f5207b7SJohn Levon } 561*1f5207b7SJohn Levon 562*1f5207b7SJohn Levon static int expand_assignment(struct expression *expr) 563*1f5207b7SJohn Levon { 564*1f5207b7SJohn Levon expand_expression(expr->left); 565*1f5207b7SJohn Levon expand_expression(expr->right); 566*1f5207b7SJohn Levon return SIDE_EFFECTS; 567*1f5207b7SJohn Levon } 568*1f5207b7SJohn Levon 569*1f5207b7SJohn Levon static int expand_addressof(struct expression *expr) 570*1f5207b7SJohn Levon { 571*1f5207b7SJohn Levon return expand_expression(expr->unop); 572*1f5207b7SJohn Levon } 573*1f5207b7SJohn Levon 574*1f5207b7SJohn Levon /* 575*1f5207b7SJohn Levon * Look up a trustable initializer value at the requested offset. 576*1f5207b7SJohn Levon * 577*1f5207b7SJohn Levon * Return NULL if no such value can be found or statically trusted. 578*1f5207b7SJohn Levon * 579*1f5207b7SJohn Levon * FIXME!! We should check that the size is right! 580*1f5207b7SJohn Levon */ 581*1f5207b7SJohn Levon static struct expression *constant_symbol_value(struct symbol *sym, int offset) 582*1f5207b7SJohn Levon { 583*1f5207b7SJohn Levon struct expression *value; 584*1f5207b7SJohn Levon 585*1f5207b7SJohn Levon if (sym->ctype.modifiers & (MOD_ASSIGNED | MOD_ADDRESSABLE)) 586*1f5207b7SJohn Levon return NULL; 587*1f5207b7SJohn Levon value = sym->initializer; 588*1f5207b7SJohn Levon if (!value) 589*1f5207b7SJohn Levon return NULL; 590*1f5207b7SJohn Levon if (value->type == EXPR_INITIALIZER) { 591*1f5207b7SJohn Levon struct expression *entry; 592*1f5207b7SJohn Levon FOR_EACH_PTR(value->expr_list, entry) { 593*1f5207b7SJohn Levon if (entry->type != EXPR_POS) { 594*1f5207b7SJohn Levon if (offset) 595*1f5207b7SJohn Levon continue; 596*1f5207b7SJohn Levon return entry; 597*1f5207b7SJohn Levon } 598*1f5207b7SJohn Levon if (entry->init_offset < offset) 599*1f5207b7SJohn Levon continue; 600*1f5207b7SJohn Levon if (entry->init_offset > offset) 601*1f5207b7SJohn Levon return NULL; 602*1f5207b7SJohn Levon return entry->init_expr; 603*1f5207b7SJohn Levon } END_FOR_EACH_PTR(entry); 604*1f5207b7SJohn Levon return NULL; 605*1f5207b7SJohn Levon } 606*1f5207b7SJohn Levon return value; 607*1f5207b7SJohn Levon } 608*1f5207b7SJohn Levon 609*1f5207b7SJohn Levon static int expand_dereference(struct expression *expr) 610*1f5207b7SJohn Levon { 611*1f5207b7SJohn Levon struct expression *unop = expr->unop; 612*1f5207b7SJohn Levon unsigned int offset; 613*1f5207b7SJohn Levon 614*1f5207b7SJohn Levon expand_expression(unop); 615*1f5207b7SJohn Levon 616*1f5207b7SJohn Levon /* 617*1f5207b7SJohn Levon * NOTE! We get a bogus warning right now for some special 618*1f5207b7SJohn Levon * cases: apparently I've screwed up the optimization of 619*1f5207b7SJohn Levon * a zero-offset dereference, and the ctype is wrong. 620*1f5207b7SJohn Levon * 621*1f5207b7SJohn Levon * Leave the warning in anyway, since this is also a good 622*1f5207b7SJohn Levon * test for me to get the type evaluation right.. 623*1f5207b7SJohn Levon */ 624*1f5207b7SJohn Levon if (expr->ctype->ctype.modifiers & MOD_NODEREF) 625*1f5207b7SJohn Levon warning(unop->pos, "dereference of noderef expression"); 626*1f5207b7SJohn Levon 627*1f5207b7SJohn Levon /* 628*1f5207b7SJohn Levon * Is it "symbol" or "symbol + offset"? 629*1f5207b7SJohn Levon */ 630*1f5207b7SJohn Levon offset = 0; 631*1f5207b7SJohn Levon if (unop->type == EXPR_BINOP && unop->op == '+') { 632*1f5207b7SJohn Levon struct expression *right = unop->right; 633*1f5207b7SJohn Levon if (right->type == EXPR_VALUE) { 634*1f5207b7SJohn Levon offset = right->value; 635*1f5207b7SJohn Levon unop = unop->left; 636*1f5207b7SJohn Levon } 637*1f5207b7SJohn Levon } 638*1f5207b7SJohn Levon 639*1f5207b7SJohn Levon if (unop->type == EXPR_SYMBOL) { 640*1f5207b7SJohn Levon struct symbol *sym = unop->symbol; 641*1f5207b7SJohn Levon struct expression *value = constant_symbol_value(sym, offset); 642*1f5207b7SJohn Levon 643*1f5207b7SJohn Levon /* Const symbol with a constant initializer? */ 644*1f5207b7SJohn Levon if (value) { 645*1f5207b7SJohn Levon /* FIXME! We should check that the size is right! */ 646*1f5207b7SJohn Levon if (value->type == EXPR_VALUE) { 647*1f5207b7SJohn Levon expr->type = EXPR_VALUE; 648*1f5207b7SJohn Levon expr->value = value->value; 649*1f5207b7SJohn Levon expr->taint = 0; 650*1f5207b7SJohn Levon return 0; 651*1f5207b7SJohn Levon } else if (value->type == EXPR_FVALUE) { 652*1f5207b7SJohn Levon expr->type = EXPR_FVALUE; 653*1f5207b7SJohn Levon expr->fvalue = value->fvalue; 654*1f5207b7SJohn Levon return 0; 655*1f5207b7SJohn Levon } 656*1f5207b7SJohn Levon } 657*1f5207b7SJohn Levon 658*1f5207b7SJohn Levon /* Direct symbol dereference? Cheap and safe */ 659*1f5207b7SJohn Levon return (sym->ctype.modifiers & (MOD_STATIC | MOD_EXTERN)) ? 2 : 1; 660*1f5207b7SJohn Levon } 661*1f5207b7SJohn Levon 662*1f5207b7SJohn Levon return UNSAFE; 663*1f5207b7SJohn Levon } 664*1f5207b7SJohn Levon 665*1f5207b7SJohn Levon static int simplify_preop(struct expression *expr) 666*1f5207b7SJohn Levon { 667*1f5207b7SJohn Levon struct expression *op = expr->unop; 668*1f5207b7SJohn Levon unsigned long long v, mask; 669*1f5207b7SJohn Levon 670*1f5207b7SJohn Levon if (op->type != EXPR_VALUE) 671*1f5207b7SJohn Levon return 0; 672*1f5207b7SJohn Levon 673*1f5207b7SJohn Levon mask = 1ULL << (expr->ctype->bit_size-1); 674*1f5207b7SJohn Levon v = op->value; 675*1f5207b7SJohn Levon switch (expr->op) { 676*1f5207b7SJohn Levon case '+': break; 677*1f5207b7SJohn Levon case '-': 678*1f5207b7SJohn Levon if (v == mask && !(expr->ctype->ctype.modifiers & MOD_UNSIGNED)) 679*1f5207b7SJohn Levon goto Overflow; 680*1f5207b7SJohn Levon v = -v; 681*1f5207b7SJohn Levon break; 682*1f5207b7SJohn Levon case '!': v = !v; break; 683*1f5207b7SJohn Levon case '~': v = ~v; break; 684*1f5207b7SJohn Levon default: return 0; 685*1f5207b7SJohn Levon } 686*1f5207b7SJohn Levon mask = mask | (mask-1); 687*1f5207b7SJohn Levon expr->value = v & mask; 688*1f5207b7SJohn Levon expr->type = EXPR_VALUE; 689*1f5207b7SJohn Levon expr->taint = op->taint; 690*1f5207b7SJohn Levon return 1; 691*1f5207b7SJohn Levon 692*1f5207b7SJohn Levon Overflow: 693*1f5207b7SJohn Levon if (!conservative) 694*1f5207b7SJohn Levon warning(expr->pos, "constant integer operation overflow"); 695*1f5207b7SJohn Levon return 0; 696*1f5207b7SJohn Levon } 697*1f5207b7SJohn Levon 698*1f5207b7SJohn Levon static int simplify_float_preop(struct expression *expr) 699*1f5207b7SJohn Levon { 700*1f5207b7SJohn Levon struct expression *op = expr->unop; 701*1f5207b7SJohn Levon long double v; 702*1f5207b7SJohn Levon 703*1f5207b7SJohn Levon if (op->type != EXPR_FVALUE) 704*1f5207b7SJohn Levon return 0; 705*1f5207b7SJohn Levon v = op->fvalue; 706*1f5207b7SJohn Levon switch (expr->op) { 707*1f5207b7SJohn Levon case '+': break; 708*1f5207b7SJohn Levon case '-': v = -v; break; 709*1f5207b7SJohn Levon default: return 0; 710*1f5207b7SJohn Levon } 711*1f5207b7SJohn Levon expr->fvalue = v; 712*1f5207b7SJohn Levon expr->type = EXPR_FVALUE; 713*1f5207b7SJohn Levon return 1; 714*1f5207b7SJohn Levon } 715*1f5207b7SJohn Levon 716*1f5207b7SJohn Levon /* 717*1f5207b7SJohn Levon * Unary post-ops: x++ and x-- 718*1f5207b7SJohn Levon */ 719*1f5207b7SJohn Levon static int expand_postop(struct expression *expr) 720*1f5207b7SJohn Levon { 721*1f5207b7SJohn Levon expand_expression(expr->unop); 722*1f5207b7SJohn Levon return SIDE_EFFECTS; 723*1f5207b7SJohn Levon } 724*1f5207b7SJohn Levon 725*1f5207b7SJohn Levon static int expand_preop(struct expression *expr) 726*1f5207b7SJohn Levon { 727*1f5207b7SJohn Levon int cost; 728*1f5207b7SJohn Levon 729*1f5207b7SJohn Levon switch (expr->op) { 730*1f5207b7SJohn Levon case '*': 731*1f5207b7SJohn Levon return expand_dereference(expr); 732*1f5207b7SJohn Levon 733*1f5207b7SJohn Levon case '&': 734*1f5207b7SJohn Levon return expand_addressof(expr); 735*1f5207b7SJohn Levon 736*1f5207b7SJohn Levon case SPECIAL_INCREMENT: 737*1f5207b7SJohn Levon case SPECIAL_DECREMENT: 738*1f5207b7SJohn Levon /* 739*1f5207b7SJohn Levon * From a type evaluation standpoint the preops are 740*1f5207b7SJohn Levon * the same as the postops 741*1f5207b7SJohn Levon */ 742*1f5207b7SJohn Levon return expand_postop(expr); 743*1f5207b7SJohn Levon 744*1f5207b7SJohn Levon default: 745*1f5207b7SJohn Levon break; 746*1f5207b7SJohn Levon } 747*1f5207b7SJohn Levon cost = expand_expression(expr->unop); 748*1f5207b7SJohn Levon 749*1f5207b7SJohn Levon if (simplify_preop(expr)) 750*1f5207b7SJohn Levon return 0; 751*1f5207b7SJohn Levon if (simplify_float_preop(expr)) 752*1f5207b7SJohn Levon return 0; 753*1f5207b7SJohn Levon return cost + 1; 754*1f5207b7SJohn Levon } 755*1f5207b7SJohn Levon 756*1f5207b7SJohn Levon static int expand_arguments(struct expression_list *head) 757*1f5207b7SJohn Levon { 758*1f5207b7SJohn Levon int cost = 0; 759*1f5207b7SJohn Levon struct expression *expr; 760*1f5207b7SJohn Levon 761*1f5207b7SJohn Levon FOR_EACH_PTR (head, expr) { 762*1f5207b7SJohn Levon cost += expand_expression(expr); 763*1f5207b7SJohn Levon } END_FOR_EACH_PTR(expr); 764*1f5207b7SJohn Levon return cost; 765*1f5207b7SJohn Levon } 766*1f5207b7SJohn Levon 767*1f5207b7SJohn Levon static int expand_cast(struct expression *expr) 768*1f5207b7SJohn Levon { 769*1f5207b7SJohn Levon int cost; 770*1f5207b7SJohn Levon struct expression *target = expr->cast_expression; 771*1f5207b7SJohn Levon 772*1f5207b7SJohn Levon cost = expand_expression(target); 773*1f5207b7SJohn Levon 774*1f5207b7SJohn Levon /* Simplify normal integer casts.. */ 775*1f5207b7SJohn Levon if (target->type == EXPR_VALUE || target->type == EXPR_FVALUE) { 776*1f5207b7SJohn Levon cast_value(expr, expr->ctype, target, target->ctype); 777*1f5207b7SJohn Levon return 0; 778*1f5207b7SJohn Levon } 779*1f5207b7SJohn Levon return cost + 1; 780*1f5207b7SJohn Levon } 781*1f5207b7SJohn Levon 782*1f5207b7SJohn Levon /* 783*1f5207b7SJohn Levon * expand a call expression with a symbol. This 784*1f5207b7SJohn Levon * should expand builtins. 785*1f5207b7SJohn Levon */ 786*1f5207b7SJohn Levon static int expand_symbol_call(struct expression *expr, int cost) 787*1f5207b7SJohn Levon { 788*1f5207b7SJohn Levon struct expression *fn = expr->fn; 789*1f5207b7SJohn Levon struct symbol *ctype = fn->ctype; 790*1f5207b7SJohn Levon 791*1f5207b7SJohn Levon if (fn->type != EXPR_PREOP) 792*1f5207b7SJohn Levon return SIDE_EFFECTS; 793*1f5207b7SJohn Levon 794*1f5207b7SJohn Levon if (ctype->op && ctype->op->expand) 795*1f5207b7SJohn Levon return ctype->op->expand(expr, cost); 796*1f5207b7SJohn Levon 797*1f5207b7SJohn Levon if (ctype->ctype.modifiers & MOD_PURE) 798*1f5207b7SJohn Levon return cost + 1; 799*1f5207b7SJohn Levon 800*1f5207b7SJohn Levon return SIDE_EFFECTS; 801*1f5207b7SJohn Levon } 802*1f5207b7SJohn Levon 803*1f5207b7SJohn Levon static int expand_call(struct expression *expr) 804*1f5207b7SJohn Levon { 805*1f5207b7SJohn Levon int cost; 806*1f5207b7SJohn Levon struct symbol *sym; 807*1f5207b7SJohn Levon struct expression *fn = expr->fn; 808*1f5207b7SJohn Levon 809*1f5207b7SJohn Levon cost = expand_arguments(expr->args); 810*1f5207b7SJohn Levon sym = fn->ctype; 811*1f5207b7SJohn Levon if (!sym) { 812*1f5207b7SJohn Levon expression_error(expr, "function has no type"); 813*1f5207b7SJohn Levon return SIDE_EFFECTS; 814*1f5207b7SJohn Levon } 815*1f5207b7SJohn Levon if (sym->type == SYM_NODE) 816*1f5207b7SJohn Levon return expand_symbol_call(expr, cost); 817*1f5207b7SJohn Levon 818*1f5207b7SJohn Levon return SIDE_EFFECTS; 819*1f5207b7SJohn Levon } 820*1f5207b7SJohn Levon 821*1f5207b7SJohn Levon static int expand_expression_list(struct expression_list *list) 822*1f5207b7SJohn Levon { 823*1f5207b7SJohn Levon int cost = 0; 824*1f5207b7SJohn Levon struct expression *expr; 825*1f5207b7SJohn Levon 826*1f5207b7SJohn Levon FOR_EACH_PTR(list, expr) { 827*1f5207b7SJohn Levon cost += expand_expression(expr); 828*1f5207b7SJohn Levon } END_FOR_EACH_PTR(expr); 829*1f5207b7SJohn Levon return cost; 830*1f5207b7SJohn Levon } 831*1f5207b7SJohn Levon 832*1f5207b7SJohn Levon /* 833*1f5207b7SJohn Levon * We can simplify nested position expressions if 834*1f5207b7SJohn Levon * this is a simple (single) positional expression. 835*1f5207b7SJohn Levon */ 836*1f5207b7SJohn Levon static int expand_pos_expression(struct expression *expr) 837*1f5207b7SJohn Levon { 838*1f5207b7SJohn Levon struct expression *nested = expr->init_expr; 839*1f5207b7SJohn Levon unsigned long offset = expr->init_offset; 840*1f5207b7SJohn Levon int nr = expr->init_nr; 841*1f5207b7SJohn Levon 842*1f5207b7SJohn Levon if (nr == 1) { 843*1f5207b7SJohn Levon switch (nested->type) { 844*1f5207b7SJohn Levon case EXPR_POS: 845*1f5207b7SJohn Levon offset += nested->init_offset; 846*1f5207b7SJohn Levon *expr = *nested; 847*1f5207b7SJohn Levon expr->init_offset = offset; 848*1f5207b7SJohn Levon nested = expr; 849*1f5207b7SJohn Levon break; 850*1f5207b7SJohn Levon 851*1f5207b7SJohn Levon case EXPR_INITIALIZER: { 852*1f5207b7SJohn Levon struct expression *reuse = nested, *entry; 853*1f5207b7SJohn Levon *expr = *nested; 854*1f5207b7SJohn Levon FOR_EACH_PTR(expr->expr_list, entry) { 855*1f5207b7SJohn Levon if (entry->type == EXPR_POS) { 856*1f5207b7SJohn Levon entry->init_offset += offset; 857*1f5207b7SJohn Levon } else { 858*1f5207b7SJohn Levon if (!reuse) { 859*1f5207b7SJohn Levon /* 860*1f5207b7SJohn Levon * This happens rarely, but it can happen 861*1f5207b7SJohn Levon * with bitfields that are all at offset 862*1f5207b7SJohn Levon * zero.. 863*1f5207b7SJohn Levon */ 864*1f5207b7SJohn Levon reuse = alloc_expression(entry->pos, EXPR_POS); 865*1f5207b7SJohn Levon } 866*1f5207b7SJohn Levon reuse->type = EXPR_POS; 867*1f5207b7SJohn Levon reuse->ctype = entry->ctype; 868*1f5207b7SJohn Levon reuse->init_offset = offset; 869*1f5207b7SJohn Levon reuse->init_nr = 1; 870*1f5207b7SJohn Levon reuse->init_expr = entry; 871*1f5207b7SJohn Levon REPLACE_CURRENT_PTR(entry, reuse); 872*1f5207b7SJohn Levon reuse = NULL; 873*1f5207b7SJohn Levon } 874*1f5207b7SJohn Levon } END_FOR_EACH_PTR(entry); 875*1f5207b7SJohn Levon nested = expr; 876*1f5207b7SJohn Levon break; 877*1f5207b7SJohn Levon } 878*1f5207b7SJohn Levon 879*1f5207b7SJohn Levon default: 880*1f5207b7SJohn Levon break; 881*1f5207b7SJohn Levon } 882*1f5207b7SJohn Levon } 883*1f5207b7SJohn Levon return expand_expression(nested); 884*1f5207b7SJohn Levon } 885*1f5207b7SJohn Levon 886*1f5207b7SJohn Levon static unsigned long bit_offset(const struct expression *expr) 887*1f5207b7SJohn Levon { 888*1f5207b7SJohn Levon unsigned long offset = 0; 889*1f5207b7SJohn Levon while (expr->type == EXPR_POS) { 890*1f5207b7SJohn Levon offset += bytes_to_bits(expr->init_offset); 891*1f5207b7SJohn Levon expr = expr->init_expr; 892*1f5207b7SJohn Levon } 893*1f5207b7SJohn Levon if (expr && expr->ctype) 894*1f5207b7SJohn Levon offset += expr->ctype->bit_offset; 895*1f5207b7SJohn Levon return offset; 896*1f5207b7SJohn Levon } 897*1f5207b7SJohn Levon 898*1f5207b7SJohn Levon static unsigned long bit_range(const struct expression *expr) 899*1f5207b7SJohn Levon { 900*1f5207b7SJohn Levon unsigned long range = 0; 901*1f5207b7SJohn Levon unsigned long size = 0; 902*1f5207b7SJohn Levon while (expr->type == EXPR_POS) { 903*1f5207b7SJohn Levon unsigned long nr = expr->init_nr; 904*1f5207b7SJohn Levon size = expr->ctype->bit_size; 905*1f5207b7SJohn Levon range += (nr - 1) * size; 906*1f5207b7SJohn Levon expr = expr->init_expr; 907*1f5207b7SJohn Levon } 908*1f5207b7SJohn Levon range += size; 909*1f5207b7SJohn Levon return range; 910*1f5207b7SJohn Levon } 911*1f5207b7SJohn Levon 912*1f5207b7SJohn Levon static int compare_expressions(const void *_a, const void *_b) 913*1f5207b7SJohn Levon { 914*1f5207b7SJohn Levon const struct expression *a = _a; 915*1f5207b7SJohn Levon const struct expression *b = _b; 916*1f5207b7SJohn Levon unsigned long a_pos = bit_offset(a); 917*1f5207b7SJohn Levon unsigned long b_pos = bit_offset(b); 918*1f5207b7SJohn Levon 919*1f5207b7SJohn Levon return (a_pos < b_pos) ? -1 : (a_pos == b_pos) ? 0 : 1; 920*1f5207b7SJohn Levon } 921*1f5207b7SJohn Levon 922*1f5207b7SJohn Levon static void sort_expression_list(struct expression_list **list) 923*1f5207b7SJohn Levon { 924*1f5207b7SJohn Levon sort_list((struct ptr_list **)list, compare_expressions); 925*1f5207b7SJohn Levon } 926*1f5207b7SJohn Levon 927*1f5207b7SJohn Levon static void verify_nonoverlapping(struct expression_list **list, struct expression *expr) 928*1f5207b7SJohn Levon { 929*1f5207b7SJohn Levon struct expression *a = NULL; 930*1f5207b7SJohn Levon unsigned long max = 0; 931*1f5207b7SJohn Levon unsigned long whole = expr->ctype->bit_size; 932*1f5207b7SJohn Levon struct expression *b; 933*1f5207b7SJohn Levon 934*1f5207b7SJohn Levon if (!Woverride_init) 935*1f5207b7SJohn Levon return; 936*1f5207b7SJohn Levon 937*1f5207b7SJohn Levon FOR_EACH_PTR(*list, b) { 938*1f5207b7SJohn Levon unsigned long off, end; 939*1f5207b7SJohn Levon if (!b->ctype || !b->ctype->bit_size) 940*1f5207b7SJohn Levon continue; 941*1f5207b7SJohn Levon off = bit_offset(b); 942*1f5207b7SJohn Levon if (a && off < max) { 943*1f5207b7SJohn Levon warning(a->pos, "Initializer entry defined twice"); 944*1f5207b7SJohn Levon info(b->pos, " also defined here"); 945*1f5207b7SJohn Levon if (!Woverride_init_all) 946*1f5207b7SJohn Levon return; 947*1f5207b7SJohn Levon } 948*1f5207b7SJohn Levon end = off + bit_range(b); 949*1f5207b7SJohn Levon if (!a && !Woverride_init_whole_range) { 950*1f5207b7SJohn Levon // If first entry is the whole range, do not let 951*1f5207b7SJohn Levon // any warning about it (this allow to initialize 952*1f5207b7SJohn Levon // an array with some default value and then override 953*1f5207b7SJohn Levon // some specific entries). 954*1f5207b7SJohn Levon if (off == 0 && end == whole) 955*1f5207b7SJohn Levon continue; 956*1f5207b7SJohn Levon } 957*1f5207b7SJohn Levon if (end > max) { 958*1f5207b7SJohn Levon max = end; 959*1f5207b7SJohn Levon a = b; 960*1f5207b7SJohn Levon } 961*1f5207b7SJohn Levon } END_FOR_EACH_PTR(b); 962*1f5207b7SJohn Levon } 963*1f5207b7SJohn Levon 964*1f5207b7SJohn Levon static int expand_expression(struct expression *expr) 965*1f5207b7SJohn Levon { 966*1f5207b7SJohn Levon if (!expr) 967*1f5207b7SJohn Levon return 0; 968*1f5207b7SJohn Levon if (!expr->ctype || expr->ctype == &bad_ctype) 969*1f5207b7SJohn Levon return UNSAFE; 970*1f5207b7SJohn Levon 971*1f5207b7SJohn Levon switch (expr->type) { 972*1f5207b7SJohn Levon case EXPR_VALUE: 973*1f5207b7SJohn Levon case EXPR_FVALUE: 974*1f5207b7SJohn Levon case EXPR_STRING: 975*1f5207b7SJohn Levon return 0; 976*1f5207b7SJohn Levon case EXPR_TYPE: 977*1f5207b7SJohn Levon case EXPR_SYMBOL: 978*1f5207b7SJohn Levon return expand_symbol_expression(expr); 979*1f5207b7SJohn Levon case EXPR_BINOP: 980*1f5207b7SJohn Levon return expand_binop(expr); 981*1f5207b7SJohn Levon 982*1f5207b7SJohn Levon case EXPR_LOGICAL: 983*1f5207b7SJohn Levon return expand_logical(expr); 984*1f5207b7SJohn Levon 985*1f5207b7SJohn Levon case EXPR_COMMA: 986*1f5207b7SJohn Levon return expand_comma(expr); 987*1f5207b7SJohn Levon 988*1f5207b7SJohn Levon case EXPR_COMPARE: 989*1f5207b7SJohn Levon return expand_compare(expr); 990*1f5207b7SJohn Levon 991*1f5207b7SJohn Levon case EXPR_ASSIGNMENT: 992*1f5207b7SJohn Levon return expand_assignment(expr); 993*1f5207b7SJohn Levon 994*1f5207b7SJohn Levon case EXPR_PREOP: 995*1f5207b7SJohn Levon return expand_preop(expr); 996*1f5207b7SJohn Levon 997*1f5207b7SJohn Levon case EXPR_POSTOP: 998*1f5207b7SJohn Levon return expand_postop(expr); 999*1f5207b7SJohn Levon 1000*1f5207b7SJohn Levon case EXPR_CAST: 1001*1f5207b7SJohn Levon case EXPR_FORCE_CAST: 1002*1f5207b7SJohn Levon case EXPR_IMPLIED_CAST: 1003*1f5207b7SJohn Levon return expand_cast(expr); 1004*1f5207b7SJohn Levon 1005*1f5207b7SJohn Levon case EXPR_CALL: 1006*1f5207b7SJohn Levon return expand_call(expr); 1007*1f5207b7SJohn Levon 1008*1f5207b7SJohn Levon case EXPR_DEREF: 1009*1f5207b7SJohn Levon warning(expr->pos, "we should not have an EXPR_DEREF left at expansion time"); 1010*1f5207b7SJohn Levon return UNSAFE; 1011*1f5207b7SJohn Levon 1012*1f5207b7SJohn Levon case EXPR_SELECT: 1013*1f5207b7SJohn Levon case EXPR_CONDITIONAL: 1014*1f5207b7SJohn Levon return expand_conditional(expr); 1015*1f5207b7SJohn Levon 1016*1f5207b7SJohn Levon case EXPR_STATEMENT: { 1017*1f5207b7SJohn Levon struct statement *stmt = expr->statement; 1018*1f5207b7SJohn Levon int cost = expand_statement(stmt); 1019*1f5207b7SJohn Levon 1020*1f5207b7SJohn Levon if (stmt->type == STMT_EXPRESSION && stmt->expression) 1021*1f5207b7SJohn Levon *expr = *stmt->expression; 1022*1f5207b7SJohn Levon return cost; 1023*1f5207b7SJohn Levon } 1024*1f5207b7SJohn Levon 1025*1f5207b7SJohn Levon case EXPR_LABEL: 1026*1f5207b7SJohn Levon return 0; 1027*1f5207b7SJohn Levon 1028*1f5207b7SJohn Levon case EXPR_INITIALIZER: 1029*1f5207b7SJohn Levon sort_expression_list(&expr->expr_list); 1030*1f5207b7SJohn Levon verify_nonoverlapping(&expr->expr_list, expr); 1031*1f5207b7SJohn Levon return expand_expression_list(expr->expr_list); 1032*1f5207b7SJohn Levon 1033*1f5207b7SJohn Levon case EXPR_IDENTIFIER: 1034*1f5207b7SJohn Levon return UNSAFE; 1035*1f5207b7SJohn Levon 1036*1f5207b7SJohn Levon case EXPR_INDEX: 1037*1f5207b7SJohn Levon return UNSAFE; 1038*1f5207b7SJohn Levon 1039*1f5207b7SJohn Levon case EXPR_SLICE: 1040*1f5207b7SJohn Levon return expand_expression(expr->base) + 1; 1041*1f5207b7SJohn Levon 1042*1f5207b7SJohn Levon case EXPR_POS: 1043*1f5207b7SJohn Levon return expand_pos_expression(expr); 1044*1f5207b7SJohn Levon 1045*1f5207b7SJohn Levon case EXPR_SIZEOF: 1046*1f5207b7SJohn Levon case EXPR_PTRSIZEOF: 1047*1f5207b7SJohn Levon case EXPR_ALIGNOF: 1048*1f5207b7SJohn Levon case EXPR_OFFSETOF: 1049*1f5207b7SJohn Levon expression_error(expr, "internal front-end error: sizeof in expansion?"); 1050*1f5207b7SJohn Levon return UNSAFE; 1051*1f5207b7SJohn Levon } 1052*1f5207b7SJohn Levon return SIDE_EFFECTS; 1053*1f5207b7SJohn Levon } 1054*1f5207b7SJohn Levon 1055*1f5207b7SJohn Levon static void expand_const_expression(struct expression *expr, const char *where) 1056*1f5207b7SJohn Levon { 1057*1f5207b7SJohn Levon if (expr) { 1058*1f5207b7SJohn Levon expand_expression(expr); 1059*1f5207b7SJohn Levon if (expr->type != EXPR_VALUE) 1060*1f5207b7SJohn Levon expression_error(expr, "Expected constant expression in %s", where); 1061*1f5207b7SJohn Levon } 1062*1f5207b7SJohn Levon } 1063*1f5207b7SJohn Levon 1064*1f5207b7SJohn Levon int expand_symbol(struct symbol *sym) 1065*1f5207b7SJohn Levon { 1066*1f5207b7SJohn Levon int retval; 1067*1f5207b7SJohn Levon struct symbol *base_type; 1068*1f5207b7SJohn Levon 1069*1f5207b7SJohn Levon if (!sym) 1070*1f5207b7SJohn Levon return 0; 1071*1f5207b7SJohn Levon base_type = sym->ctype.base_type; 1072*1f5207b7SJohn Levon if (!base_type) 1073*1f5207b7SJohn Levon return 0; 1074*1f5207b7SJohn Levon 1075*1f5207b7SJohn Levon retval = expand_expression(sym->initializer); 1076*1f5207b7SJohn Levon /* expand the body of the symbol */ 1077*1f5207b7SJohn Levon if (base_type->type == SYM_FN) { 1078*1f5207b7SJohn Levon if (base_type->stmt) 1079*1f5207b7SJohn Levon expand_statement(base_type->stmt); 1080*1f5207b7SJohn Levon } 1081*1f5207b7SJohn Levon return retval; 1082*1f5207b7SJohn Levon } 1083*1f5207b7SJohn Levon 1084*1f5207b7SJohn Levon static void expand_return_expression(struct statement *stmt) 1085*1f5207b7SJohn Levon { 1086*1f5207b7SJohn Levon expand_expression(stmt->expression); 1087*1f5207b7SJohn Levon } 1088*1f5207b7SJohn Levon 1089*1f5207b7SJohn Levon static int expand_if_statement(struct statement *stmt) 1090*1f5207b7SJohn Levon { 1091*1f5207b7SJohn Levon struct expression *expr = stmt->if_conditional; 1092*1f5207b7SJohn Levon 1093*1f5207b7SJohn Levon if (!expr || !expr->ctype || expr->ctype == &bad_ctype) 1094*1f5207b7SJohn Levon return UNSAFE; 1095*1f5207b7SJohn Levon 1096*1f5207b7SJohn Levon expand_expression(expr); 1097*1f5207b7SJohn Levon 1098*1f5207b7SJohn Levon /* This is only valid if nobody jumps into the "dead" side */ 1099*1f5207b7SJohn Levon #if 0 1100*1f5207b7SJohn Levon /* Simplify constant conditionals without even evaluating the false side */ 1101*1f5207b7SJohn Levon if (expr->type == EXPR_VALUE) { 1102*1f5207b7SJohn Levon struct statement *simple; 1103*1f5207b7SJohn Levon simple = expr->value ? stmt->if_true : stmt->if_false; 1104*1f5207b7SJohn Levon 1105*1f5207b7SJohn Levon /* Nothing? */ 1106*1f5207b7SJohn Levon if (!simple) { 1107*1f5207b7SJohn Levon stmt->type = STMT_NONE; 1108*1f5207b7SJohn Levon return 0; 1109*1f5207b7SJohn Levon } 1110*1f5207b7SJohn Levon expand_statement(simple); 1111*1f5207b7SJohn Levon *stmt = *simple; 1112*1f5207b7SJohn Levon return SIDE_EFFECTS; 1113*1f5207b7SJohn Levon } 1114*1f5207b7SJohn Levon #endif 1115*1f5207b7SJohn Levon expand_statement(stmt->if_true); 1116*1f5207b7SJohn Levon expand_statement(stmt->if_false); 1117*1f5207b7SJohn Levon return SIDE_EFFECTS; 1118*1f5207b7SJohn Levon } 1119*1f5207b7SJohn Levon 1120*1f5207b7SJohn Levon /* 1121*1f5207b7SJohn Levon * Expanding a compound statement is really just 1122*1f5207b7SJohn Levon * about adding up the costs of each individual 1123*1f5207b7SJohn Levon * statement. 1124*1f5207b7SJohn Levon * 1125*1f5207b7SJohn Levon * We also collapse a simple compound statement: 1126*1f5207b7SJohn Levon * this would trigger for simple inline functions, 1127*1f5207b7SJohn Levon * except we would have to check the "return" 1128*1f5207b7SJohn Levon * symbol usage. Next time. 1129*1f5207b7SJohn Levon */ 1130*1f5207b7SJohn Levon static int expand_compound(struct statement *stmt) 1131*1f5207b7SJohn Levon { 1132*1f5207b7SJohn Levon struct statement *s, *last; 1133*1f5207b7SJohn Levon int cost, statements; 1134*1f5207b7SJohn Levon 1135*1f5207b7SJohn Levon if (stmt->ret) 1136*1f5207b7SJohn Levon expand_symbol(stmt->ret); 1137*1f5207b7SJohn Levon 1138*1f5207b7SJohn Levon last = stmt->args; 1139*1f5207b7SJohn Levon cost = expand_statement(last); 1140*1f5207b7SJohn Levon statements = last != NULL; 1141*1f5207b7SJohn Levon FOR_EACH_PTR(stmt->stmts, s) { 1142*1f5207b7SJohn Levon statements++; 1143*1f5207b7SJohn Levon last = s; 1144*1f5207b7SJohn Levon cost += expand_statement(s); 1145*1f5207b7SJohn Levon } END_FOR_EACH_PTR(s); 1146*1f5207b7SJohn Levon 1147*1f5207b7SJohn Levon if (statements == 1 && !stmt->ret) 1148*1f5207b7SJohn Levon *stmt = *last; 1149*1f5207b7SJohn Levon 1150*1f5207b7SJohn Levon return cost; 1151*1f5207b7SJohn Levon } 1152*1f5207b7SJohn Levon 1153*1f5207b7SJohn Levon static int expand_statement(struct statement *stmt) 1154*1f5207b7SJohn Levon { 1155*1f5207b7SJohn Levon if (!stmt) 1156*1f5207b7SJohn Levon return 0; 1157*1f5207b7SJohn Levon 1158*1f5207b7SJohn Levon switch (stmt->type) { 1159*1f5207b7SJohn Levon case STMT_DECLARATION: { 1160*1f5207b7SJohn Levon struct symbol *sym; 1161*1f5207b7SJohn Levon FOR_EACH_PTR(stmt->declaration, sym) { 1162*1f5207b7SJohn Levon expand_symbol(sym); 1163*1f5207b7SJohn Levon } END_FOR_EACH_PTR(sym); 1164*1f5207b7SJohn Levon return SIDE_EFFECTS; 1165*1f5207b7SJohn Levon } 1166*1f5207b7SJohn Levon 1167*1f5207b7SJohn Levon case STMT_RETURN: 1168*1f5207b7SJohn Levon expand_return_expression(stmt); 1169*1f5207b7SJohn Levon return SIDE_EFFECTS; 1170*1f5207b7SJohn Levon 1171*1f5207b7SJohn Levon case STMT_EXPRESSION: 1172*1f5207b7SJohn Levon return expand_expression(stmt->expression); 1173*1f5207b7SJohn Levon 1174*1f5207b7SJohn Levon case STMT_COMPOUND: 1175*1f5207b7SJohn Levon return expand_compound(stmt); 1176*1f5207b7SJohn Levon 1177*1f5207b7SJohn Levon case STMT_IF: 1178*1f5207b7SJohn Levon return expand_if_statement(stmt); 1179*1f5207b7SJohn Levon 1180*1f5207b7SJohn Levon case STMT_ITERATOR: 1181*1f5207b7SJohn Levon expand_expression(stmt->iterator_pre_condition); 1182*1f5207b7SJohn Levon expand_expression(stmt->iterator_post_condition); 1183*1f5207b7SJohn Levon expand_statement(stmt->iterator_pre_statement); 1184*1f5207b7SJohn Levon expand_statement(stmt->iterator_statement); 1185*1f5207b7SJohn Levon expand_statement(stmt->iterator_post_statement); 1186*1f5207b7SJohn Levon return SIDE_EFFECTS; 1187*1f5207b7SJohn Levon 1188*1f5207b7SJohn Levon case STMT_SWITCH: 1189*1f5207b7SJohn Levon expand_expression(stmt->switch_expression); 1190*1f5207b7SJohn Levon expand_statement(stmt->switch_statement); 1191*1f5207b7SJohn Levon return SIDE_EFFECTS; 1192*1f5207b7SJohn Levon 1193*1f5207b7SJohn Levon case STMT_CASE: 1194*1f5207b7SJohn Levon expand_const_expression(stmt->case_expression, "case statement"); 1195*1f5207b7SJohn Levon expand_const_expression(stmt->case_to, "case statement"); 1196*1f5207b7SJohn Levon expand_statement(stmt->case_statement); 1197*1f5207b7SJohn Levon return SIDE_EFFECTS; 1198*1f5207b7SJohn Levon 1199*1f5207b7SJohn Levon case STMT_LABEL: 1200*1f5207b7SJohn Levon expand_statement(stmt->label_statement); 1201*1f5207b7SJohn Levon return SIDE_EFFECTS; 1202*1f5207b7SJohn Levon 1203*1f5207b7SJohn Levon case STMT_GOTO: 1204*1f5207b7SJohn Levon expand_expression(stmt->goto_expression); 1205*1f5207b7SJohn Levon return SIDE_EFFECTS; 1206*1f5207b7SJohn Levon 1207*1f5207b7SJohn Levon case STMT_NONE: 1208*1f5207b7SJohn Levon break; 1209*1f5207b7SJohn Levon case STMT_ASM: 1210*1f5207b7SJohn Levon /* FIXME! Do the asm parameter evaluation! */ 1211*1f5207b7SJohn Levon break; 1212*1f5207b7SJohn Levon case STMT_CONTEXT: 1213*1f5207b7SJohn Levon expand_expression(stmt->expression); 1214*1f5207b7SJohn Levon break; 1215*1f5207b7SJohn Levon case STMT_RANGE: 1216*1f5207b7SJohn Levon expand_expression(stmt->range_expression); 1217*1f5207b7SJohn Levon expand_expression(stmt->range_low); 1218*1f5207b7SJohn Levon expand_expression(stmt->range_high); 1219*1f5207b7SJohn Levon break; 1220*1f5207b7SJohn Levon } 1221*1f5207b7SJohn Levon return SIDE_EFFECTS; 1222*1f5207b7SJohn Levon } 1223*1f5207b7SJohn Levon 1224*1f5207b7SJohn Levon static inline int bad_integer_constant_expression(struct expression *expr) 1225*1f5207b7SJohn Levon { 1226*1f5207b7SJohn Levon if (!(expr->flags & CEF_ICE)) 1227*1f5207b7SJohn Levon return 1; 1228*1f5207b7SJohn Levon if (expr->taint & Taint_comma) 1229*1f5207b7SJohn Levon return 1; 1230*1f5207b7SJohn Levon return 0; 1231*1f5207b7SJohn Levon } 1232*1f5207b7SJohn Levon 1233*1f5207b7SJohn Levon static long long __get_expression_value(struct expression *expr, int strict) 1234*1f5207b7SJohn Levon { 1235*1f5207b7SJohn Levon long long value, mask; 1236*1f5207b7SJohn Levon struct symbol *ctype; 1237*1f5207b7SJohn Levon 1238*1f5207b7SJohn Levon if (!expr) 1239*1f5207b7SJohn Levon return 0; 1240*1f5207b7SJohn Levon ctype = evaluate_expression(expr); 1241*1f5207b7SJohn Levon if (!ctype) { 1242*1f5207b7SJohn Levon expression_error(expr, "bad constant expression type"); 1243*1f5207b7SJohn Levon return 0; 1244*1f5207b7SJohn Levon } 1245*1f5207b7SJohn Levon expand_expression(expr); 1246*1f5207b7SJohn Levon if (expr->type != EXPR_VALUE) { 1247*1f5207b7SJohn Levon if (strict != 2) 1248*1f5207b7SJohn Levon expression_error(expr, "bad constant expression"); 1249*1f5207b7SJohn Levon return 0; 1250*1f5207b7SJohn Levon } 1251*1f5207b7SJohn Levon if ((strict == 1) && bad_integer_constant_expression(expr)) { 1252*1f5207b7SJohn Levon expression_error(expr, "bad integer constant expression"); 1253*1f5207b7SJohn Levon return 0; 1254*1f5207b7SJohn Levon } 1255*1f5207b7SJohn Levon 1256*1f5207b7SJohn Levon value = expr->value; 1257*1f5207b7SJohn Levon mask = 1ULL << (ctype->bit_size-1); 1258*1f5207b7SJohn Levon 1259*1f5207b7SJohn Levon if (value & mask) { 1260*1f5207b7SJohn Levon while (ctype->type != SYM_BASETYPE) 1261*1f5207b7SJohn Levon ctype = ctype->ctype.base_type; 1262*1f5207b7SJohn Levon if (!(ctype->ctype.modifiers & MOD_UNSIGNED)) 1263*1f5207b7SJohn Levon value = value | mask | ~(mask-1); 1264*1f5207b7SJohn Levon } 1265*1f5207b7SJohn Levon return value; 1266*1f5207b7SJohn Levon } 1267*1f5207b7SJohn Levon 1268*1f5207b7SJohn Levon long long get_expression_value(struct expression *expr) 1269*1f5207b7SJohn Levon { 1270*1f5207b7SJohn Levon return __get_expression_value(expr, 0); 1271*1f5207b7SJohn Levon } 1272*1f5207b7SJohn Levon 1273*1f5207b7SJohn Levon long long const_expression_value(struct expression *expr) 1274*1f5207b7SJohn Levon { 1275*1f5207b7SJohn Levon return __get_expression_value(expr, 1); 1276*1f5207b7SJohn Levon } 1277*1f5207b7SJohn Levon 1278*1f5207b7SJohn Levon long long get_expression_value_silent(struct expression *expr) 1279*1f5207b7SJohn Levon { 1280*1f5207b7SJohn Levon 1281*1f5207b7SJohn Levon return __get_expression_value(expr, 2); 1282*1f5207b7SJohn Levon } 1283*1f5207b7SJohn Levon 1284*1f5207b7SJohn Levon int expr_truth_value(struct expression *expr) 1285*1f5207b7SJohn Levon { 1286*1f5207b7SJohn Levon const int saved = conservative; 1287*1f5207b7SJohn Levon struct symbol *ctype; 1288*1f5207b7SJohn Levon 1289*1f5207b7SJohn Levon if (!expr) 1290*1f5207b7SJohn Levon return 0; 1291*1f5207b7SJohn Levon 1292*1f5207b7SJohn Levon ctype = evaluate_expression(expr); 1293*1f5207b7SJohn Levon if (!ctype) 1294*1f5207b7SJohn Levon return -1; 1295*1f5207b7SJohn Levon 1296*1f5207b7SJohn Levon conservative = 1; 1297*1f5207b7SJohn Levon expand_expression(expr); 1298*1f5207b7SJohn Levon conservative = saved; 1299*1f5207b7SJohn Levon 1300*1f5207b7SJohn Levon redo: 1301*1f5207b7SJohn Levon switch (expr->type) { 1302*1f5207b7SJohn Levon case EXPR_COMMA: 1303*1f5207b7SJohn Levon expr = expr->right; 1304*1f5207b7SJohn Levon goto redo; 1305*1f5207b7SJohn Levon case EXPR_VALUE: 1306*1f5207b7SJohn Levon return expr->value != 0; 1307*1f5207b7SJohn Levon case EXPR_FVALUE: 1308*1f5207b7SJohn Levon return expr->fvalue != 0; 1309*1f5207b7SJohn Levon default: 1310*1f5207b7SJohn Levon return -1; 1311*1f5207b7SJohn Levon } 1312*1f5207b7SJohn Levon } 1313*1f5207b7SJohn Levon 1314*1f5207b7SJohn Levon int is_zero_constant(struct expression *expr) 1315*1f5207b7SJohn Levon { 1316*1f5207b7SJohn Levon const int saved = conservative; 1317*1f5207b7SJohn Levon conservative = 1; 1318*1f5207b7SJohn Levon expand_expression(expr); 1319*1f5207b7SJohn Levon conservative = saved; 1320*1f5207b7SJohn Levon return expr->type == EXPR_VALUE && !expr->value; 1321*1f5207b7SJohn Levon } 1322