Annotation of gdb/valarith.c, revision 1.1.1.1

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: 
                    122:   if ((TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_FLT
                    123:        &&
                    124:        TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT)
                    125:       ||
                    126:       (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_FLT
                    127:        &&
                    128:        TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_INT))
                    129:     error ("Argument to arithmetic operation not a number.");
                    130: 
                    131:   if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_FLT
                    132:       ||
                    133:       TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_FLT)
                    134:     {
                    135:       double v1, v2, v;
                    136:       v1 = value_as_double (arg1);
                    137:       v2 = value_as_double (arg2);
                    138:       switch (op)
                    139:        {
                    140:        case BINOP_ADD:
                    141:          v = v1 + v2;
                    142:          break;
                    143: 
                    144:        case BINOP_SUB:
                    145:          v = v1 - v2;
                    146:          break;
                    147: 
                    148:        case BINOP_MUL:
                    149:          v = v1 * v2;
                    150:          break;
                    151: 
                    152:        case BINOP_DIV:
                    153:          v = v1 / v2;
                    154:          break;
                    155: 
                    156:        default:
                    157:          error ("Integer-only operation on floating point number.");
                    158:        }
                    159: 
                    160:       val = allocate_value (builtin_type_double);
                    161:       *(double *) VALUE_CONTENTS (val) = v;
                    162:     }
                    163:   else
                    164:     {
                    165:       long v1, v2, v;
                    166:       v1 = value_as_long (arg1);
                    167:       v2 = value_as_long (arg2);
                    168: 
                    169:       switch (op)
                    170:        {
                    171:        case BINOP_ADD:
                    172:          v = v1 + v2;
                    173:          break;
                    174: 
                    175:        case BINOP_SUB:
                    176:          v = v1 - v2;
                    177:          break;
                    178: 
                    179:        case BINOP_MUL:
                    180:          v = v1 * v2;
                    181:          break;
                    182: 
                    183:        case BINOP_DIV:
                    184:          v = v1 / v2;
                    185:          break;
                    186: 
                    187:        case BINOP_REM:
                    188:          v = v1 % v2;
                    189:          break;
                    190: 
                    191:        case BINOP_LSH:
                    192:          v = v1 << v2;
                    193:          break;
                    194: 
                    195:        case BINOP_RSH:
                    196:          v = v1 >> v2;
                    197:          break;
                    198: 
                    199:        case BINOP_LOGAND:
                    200:          v = v1 & v2;
                    201:          break;
                    202: 
                    203:        case BINOP_LOGIOR:
                    204:          v = v1 | v2;
                    205:          break;
                    206: 
                    207:        case BINOP_LOGXOR:
                    208:          v = v1 ^ v2;
                    209:          break;
                    210: 
                    211:        case BINOP_AND:
                    212:          v = v1 && v2;
                    213:          break;
                    214: 
                    215:        case BINOP_OR:
                    216:          v = v1 || v2;
                    217:          break;
                    218: 
                    219:        default:
                    220:          error ("Invalid binary operation on numbers.");
                    221:        }
                    222: 
                    223:       val = allocate_value (builtin_type_long);
                    224:       *(long *) VALUE_CONTENTS (val) = v;
                    225:     }
                    226: 
                    227:   return val;
                    228: }
                    229: 
                    230: /* Simulate the C operator ! -- return 1 if ARG1 contains zeros.  */
                    231: 
                    232: int
                    233: value_zerop (arg1)
                    234:      value arg1;
                    235: {
                    236:   register int len;
                    237:   register char *p;
                    238: 
                    239:   COERCE_ARRAY (arg1);
                    240: 
                    241:   len = TYPE_LENGTH (VALUE_TYPE (arg1));
                    242:   p = VALUE_CONTENTS (arg1);
                    243: 
                    244:   while (--len >= 0)
                    245:     {
                    246:       if (*p++)
                    247:        break;
                    248:     }
                    249: 
                    250:   return len < 0;
                    251: }
                    252: 
                    253: /* Simulate the C operator == by returning a 1
                    254:    iff ARG1 and ARG2 have equal contents.  */
                    255: 
                    256: int
                    257: value_equal (arg1, arg2)
                    258:      register value arg1, arg2;
                    259: 
                    260: {
                    261:   register int len;
                    262:   register char *p1, *p2;
                    263:   enum type_code code1;
                    264:   enum type_code code2;
                    265: 
                    266:   COERCE_ARRAY (arg1);
                    267:   COERCE_ARRAY (arg2);
                    268: 
                    269:   code1 = TYPE_CODE (VALUE_TYPE (arg1));
                    270:   code2 = TYPE_CODE (VALUE_TYPE (arg2));
                    271: 
                    272:   if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
                    273:     return value_as_long (arg1) == value_as_long (arg2);
                    274:   else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
                    275:           && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
                    276:     return value_as_double (arg1) == value_as_double (arg2);
                    277:   else if ((code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_INT)
                    278:           || (code2 == TYPE_CODE_PTR && code1 == TYPE_CODE_INT))
                    279:     return value_as_long (arg1) == value_as_long (arg2);
                    280:   else if (code1 == code2
                    281:           && ((len = TYPE_LENGTH (VALUE_TYPE (arg1)))
                    282:               == TYPE_LENGTH (VALUE_TYPE (arg2))))
                    283:     {
                    284:       p1 = VALUE_CONTENTS (arg1);
                    285:       p2 = VALUE_CONTENTS (arg2);
                    286:       while (--len >= 0)
                    287:        {
                    288:          if (*p1++ != *p2++)
                    289:            break;
                    290:        }
                    291:       return len < 0;
                    292:     }
                    293:   else
                    294:     error ("Invalid type combination in equality test.");
                    295: }
                    296: 
                    297: /* Simulate the C operator < by returning 1
                    298:    iff ARG1's contents are less than ARG2's.  */
                    299: 
                    300: int
                    301: value_less (arg1, arg2)
                    302:      register value arg1, arg2;
                    303: {
                    304:   register enum type_code code1;
                    305:   register enum type_code code2;
                    306: 
                    307:   COERCE_ARRAY (arg1);
                    308:   COERCE_ARRAY (arg2);
                    309: 
                    310:   code1 = TYPE_CODE (VALUE_TYPE (arg1));
                    311:   code2 = TYPE_CODE (VALUE_TYPE (arg2));
                    312: 
                    313:   if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
                    314:     return value_as_long (arg1) < value_as_long (arg2);
                    315:   else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
                    316:           && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
                    317:     return value_as_double (arg1) < value_as_double (arg2);
                    318:   else if ((code1 == TYPE_CODE_PTR || code1 == TYPE_CODE_INT)
                    319:           && (code2 == TYPE_CODE_PTR || code2 == TYPE_CODE_INT))
                    320:     return value_as_long (arg1) < value_as_long (arg2);
                    321:   else
                    322:     error ("Invalid type combination in ordering comparison.");
                    323: }
                    324: 
                    325: /* The unary operators - and ~.  Both free the argument ARG1.  */
                    326: 
                    327: value
                    328: value_neg (arg1)
                    329:      register value arg1;
                    330: {
                    331:   register struct type *type = VALUE_TYPE (arg1);
                    332: 
                    333:   if (TYPE_CODE (type) == TYPE_CODE_FLT)
                    334:     return value_from_double (type, - value_as_double (arg1));
                    335:   else if (TYPE_CODE (type) == TYPE_CODE_INT)
                    336:     return value_from_long (type, - value_as_long (arg1));
                    337:   else
                    338:     error ("Argument to negate operation not a number.");
                    339: }
                    340: 
                    341: value
                    342: value_lognot (arg1)
                    343:      register value arg1;
                    344: {
                    345:   if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT)
                    346:     error ("Argument to complement operation not an integer.");
                    347: 
                    348:   return value_from_long (VALUE_TYPE (arg1), ~ value_as_long (arg1));
                    349: }
                    350: 
                    351: static
                    352: initialize ()
                    353: {
                    354: }
                    355: 
                    356: END_FILE

unix.superglobalmegacorp.com

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