Annotation of gdb/valarith.c, revision 1.1.1.2

1.1       root        1: /* Perform arithmetic and other operations on values, for GDB.
                      2:    Copyright (C) 1986 Free Software Foundation, Inc.
                      3: 
                      4: GDB is distributed in the hope that it will be useful, but WITHOUT ANY
                      5: WARRANTY.  No author or distributor accepts responsibility to anyone
                      6: for the consequences of using it or for whether it serves any
                      7: particular purpose or works at all, unless he says so in writing.
                      8: Refer to the GDB General Public License for full details.
                      9: 
                     10: Everyone is granted permission to copy, modify and redistribute GDB,
                     11: but only under the conditions described in the GDB General Public
                     12: License.  A copy of this license is supposed to have been given to you
                     13: along with GDB so you can know your rights and responsibilities.  It
                     14: should be in a file named COPYING.  Among other things, the copyright
                     15: notice and this notice must be preserved on all copies.
                     16: 
                     17: In other words, go ahead and share GDB, but don't try to stop
                     18: anyone else from sharing it farther.  Help stamp out software hoarding!
                     19: */
                     20: 
                     21: #include "defs.h"
                     22: #include "initialize.h"
                     23: #include "param.h"
                     24: #include "symtab.h"
                     25: #include "value.h"
                     26: #include "expression.h"
                     27: 
                     28: START_FILE
                     29: 
                     30: value
                     31: value_add (arg1, arg2)
                     32:        value arg1, arg2;
                     33: {
                     34:   register value val, valint, valptr;
                     35:   register int len;
                     36: 
                     37:   COERCE_ARRAY (arg1);
                     38:   COERCE_ARRAY (arg2);
                     39: 
                     40:   if ((TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR
                     41:        || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_PTR)
                     42:       &&
                     43:       (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT
                     44:        || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_INT))
                     45:     /* Exactly one argument is a pointer, and one is an integer.  */
                     46:     {
                     47:       if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR)
                     48:        {
                     49:          valptr = arg1;
                     50:          valint = arg2;
                     51:        }
                     52:       else
                     53:        {
                     54:          valptr = arg2;
                     55:          valint = arg1;
                     56:        }
                     57:       len = TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (valptr)));
                     58:       if (len == 0) len = 1;   /* For (void *) */
                     59:       val = value_from_long (builtin_type_long,
                     60:                             value_as_long (valptr)
                     61:                             + (len * value_as_long (valint)));
                     62:       VALUE_TYPE (val) = VALUE_TYPE (valptr);
                     63:       return val;
                     64:     }
                     65: 
                     66:   return value_binop (arg1, arg2, BINOP_ADD);
                     67: }
                     68: 
                     69: value
                     70: value_sub (arg1, arg2)
                     71:        value arg1, arg2;
                     72: {
                     73:   register value val;
                     74: 
                     75:   COERCE_ARRAY (arg1);
                     76:   COERCE_ARRAY (arg2);
                     77: 
                     78:   if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR
                     79:       && 
                     80:       TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_INT)
                     81:     {
                     82:       val = value_from_long (builtin_type_long,
                     83:                             value_as_long (arg1)
                     84:                             - TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) * value_as_long (arg2));
                     85:       VALUE_TYPE (val) = VALUE_TYPE (arg1);
                     86:       return val;
                     87:     }
                     88: 
                     89:   if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR
                     90:       && 
                     91:       VALUE_TYPE (arg1) == VALUE_TYPE (arg2))
                     92:     {
                     93:       val = value_from_long (builtin_type_long,
                     94:                             (value_as_long (arg1) - value_as_long (arg2))
                     95:                             / TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))));
                     96:       return val;
                     97:     }
                     98: 
                     99:   return value_binop (arg1, arg2, BINOP_SUB);
                    100: }
                    101: 
                    102: /* Return the value of ARRAY[IDX].  */
                    103: 
                    104: value
                    105: value_subscript (array, idx)
                    106:      value array, idx;
                    107: {
                    108:   return value_ind (value_add (array, idx));
                    109: }
                    110: 
                    111: /* Perform a binary operation on two integers or two floats.
                    112:    Does not support addition and subtraction on pointers;
                    113:    use value_add or value_sub if you want to handle those possibilities.  */
                    114: 
                    115: value
                    116: value_binop (arg1, arg2, op)
                    117:      value arg1, arg2;
                    118:      int op;
                    119: {
                    120:   register value val;
                    121: 
1.1.1.2 ! root      122:   COERCE_ENUM (arg1);
        !           123:   COERCE_ENUM (arg2);
        !           124: 
1.1       root      125:   if ((TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_FLT
                    126:        &&
                    127:        TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT)
                    128:       ||
                    129:       (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_FLT
                    130:        &&
                    131:        TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_INT))
                    132:     error ("Argument to arithmetic operation not a number.");
                    133: 
                    134:   if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_FLT
                    135:       ||
                    136:       TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_FLT)
                    137:     {
                    138:       double v1, v2, v;
                    139:       v1 = value_as_double (arg1);
                    140:       v2 = value_as_double (arg2);
                    141:       switch (op)
                    142:        {
                    143:        case BINOP_ADD:
                    144:          v = v1 + v2;
                    145:          break;
                    146: 
                    147:        case BINOP_SUB:
                    148:          v = v1 - v2;
                    149:          break;
                    150: 
                    151:        case BINOP_MUL:
                    152:          v = v1 * v2;
                    153:          break;
                    154: 
                    155:        case BINOP_DIV:
                    156:          v = v1 / v2;
                    157:          break;
                    158: 
                    159:        default:
                    160:          error ("Integer-only operation on floating point number.");
                    161:        }
                    162: 
                    163:       val = allocate_value (builtin_type_double);
                    164:       *(double *) VALUE_CONTENTS (val) = v;
                    165:     }
                    166:   else
                    167:     {
                    168:       long v1, v2, v;
                    169:       v1 = value_as_long (arg1);
                    170:       v2 = value_as_long (arg2);
                    171: 
                    172:       switch (op)
                    173:        {
                    174:        case BINOP_ADD:
                    175:          v = v1 + v2;
                    176:          break;
                    177: 
                    178:        case BINOP_SUB:
                    179:          v = v1 - v2;
                    180:          break;
                    181: 
                    182:        case BINOP_MUL:
                    183:          v = v1 * v2;
                    184:          break;
                    185: 
                    186:        case BINOP_DIV:
                    187:          v = v1 / v2;
                    188:          break;
                    189: 
                    190:        case BINOP_REM:
                    191:          v = v1 % v2;
                    192:          break;
                    193: 
                    194:        case BINOP_LSH:
                    195:          v = v1 << v2;
                    196:          break;
                    197: 
                    198:        case BINOP_RSH:
                    199:          v = v1 >> v2;
                    200:          break;
                    201: 
                    202:        case BINOP_LOGAND:
                    203:          v = v1 & v2;
                    204:          break;
                    205: 
                    206:        case BINOP_LOGIOR:
                    207:          v = v1 | v2;
                    208:          break;
                    209: 
                    210:        case BINOP_LOGXOR:
                    211:          v = v1 ^ v2;
                    212:          break;
                    213: 
                    214:        case BINOP_AND:
                    215:          v = v1 && v2;
                    216:          break;
                    217: 
                    218:        case BINOP_OR:
                    219:          v = v1 || v2;
                    220:          break;
                    221: 
                    222:        default:
                    223:          error ("Invalid binary operation on numbers.");
                    224:        }
                    225: 
                    226:       val = allocate_value (builtin_type_long);
                    227:       *(long *) VALUE_CONTENTS (val) = v;
                    228:     }
                    229: 
                    230:   return val;
                    231: }
                    232: 
                    233: /* Simulate the C operator ! -- return 1 if ARG1 contains zeros.  */
                    234: 
                    235: int
                    236: value_zerop (arg1)
                    237:      value arg1;
                    238: {
                    239:   register int len;
                    240:   register char *p;
                    241: 
                    242:   COERCE_ARRAY (arg1);
                    243: 
                    244:   len = TYPE_LENGTH (VALUE_TYPE (arg1));
                    245:   p = VALUE_CONTENTS (arg1);
                    246: 
                    247:   while (--len >= 0)
                    248:     {
                    249:       if (*p++)
                    250:        break;
                    251:     }
                    252: 
                    253:   return len < 0;
                    254: }
                    255: 
                    256: /* Simulate the C operator == by returning a 1
                    257:    iff ARG1 and ARG2 have equal contents.  */
                    258: 
                    259: int
                    260: value_equal (arg1, arg2)
                    261:      register value arg1, arg2;
                    262: 
                    263: {
                    264:   register int len;
                    265:   register char *p1, *p2;
                    266:   enum type_code code1;
                    267:   enum type_code code2;
                    268: 
                    269:   COERCE_ARRAY (arg1);
                    270:   COERCE_ARRAY (arg2);
                    271: 
                    272:   code1 = TYPE_CODE (VALUE_TYPE (arg1));
                    273:   code2 = TYPE_CODE (VALUE_TYPE (arg2));
                    274: 
                    275:   if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
                    276:     return value_as_long (arg1) == value_as_long (arg2);
                    277:   else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
                    278:           && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
                    279:     return value_as_double (arg1) == value_as_double (arg2);
                    280:   else if ((code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_INT)
                    281:           || (code2 == TYPE_CODE_PTR && code1 == TYPE_CODE_INT))
                    282:     return value_as_long (arg1) == value_as_long (arg2);
                    283:   else if (code1 == code2
                    284:           && ((len = TYPE_LENGTH (VALUE_TYPE (arg1)))
                    285:               == TYPE_LENGTH (VALUE_TYPE (arg2))))
                    286:     {
                    287:       p1 = VALUE_CONTENTS (arg1);
                    288:       p2 = VALUE_CONTENTS (arg2);
                    289:       while (--len >= 0)
                    290:        {
                    291:          if (*p1++ != *p2++)
                    292:            break;
                    293:        }
                    294:       return len < 0;
                    295:     }
                    296:   else
                    297:     error ("Invalid type combination in equality test.");
                    298: }
                    299: 
                    300: /* Simulate the C operator < by returning 1
                    301:    iff ARG1's contents are less than ARG2's.  */
                    302: 
                    303: int
                    304: value_less (arg1, arg2)
                    305:      register value arg1, arg2;
                    306: {
                    307:   register enum type_code code1;
                    308:   register enum type_code code2;
                    309: 
                    310:   COERCE_ARRAY (arg1);
                    311:   COERCE_ARRAY (arg2);
                    312: 
                    313:   code1 = TYPE_CODE (VALUE_TYPE (arg1));
                    314:   code2 = TYPE_CODE (VALUE_TYPE (arg2));
                    315: 
                    316:   if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
                    317:     return value_as_long (arg1) < value_as_long (arg2);
                    318:   else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
                    319:           && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
                    320:     return value_as_double (arg1) < value_as_double (arg2);
                    321:   else if ((code1 == TYPE_CODE_PTR || code1 == TYPE_CODE_INT)
                    322:           && (code2 == TYPE_CODE_PTR || code2 == TYPE_CODE_INT))
                    323:     return value_as_long (arg1) < value_as_long (arg2);
                    324:   else
                    325:     error ("Invalid type combination in ordering comparison.");
                    326: }
                    327: 
                    328: /* The unary operators - and ~.  Both free the argument ARG1.  */
                    329: 
                    330: value
                    331: value_neg (arg1)
                    332:      register value arg1;
                    333: {
1.1.1.2 ! root      334:   register struct type *type;
        !           335: 
        !           336:   COERCE_ENUM (arg1);
        !           337: 
        !           338:   type = VALUE_TYPE (arg1);
1.1       root      339: 
                    340:   if (TYPE_CODE (type) == TYPE_CODE_FLT)
                    341:     return value_from_double (type, - value_as_double (arg1));
                    342:   else if (TYPE_CODE (type) == TYPE_CODE_INT)
                    343:     return value_from_long (type, - value_as_long (arg1));
                    344:   else
                    345:     error ("Argument to negate operation not a number.");
                    346: }
                    347: 
                    348: value
                    349: value_lognot (arg1)
                    350:      register value arg1;
                    351: {
1.1.1.2 ! root      352:   COERCE_ENUM (arg1);
        !           353: 
1.1       root      354:   if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT)
                    355:     error ("Argument to complement operation not an integer.");
                    356: 
                    357:   return value_from_long (VALUE_TYPE (arg1), ~ value_as_long (arg1));
                    358: }
                    359: 
                    360: static
                    361: initialize ()
                    362: {
                    363: }
                    364: 
                    365: END_FILE

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.