|
|
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: COERCE_ENUM (arg1); ! 123: COERCE_ENUM (arg2); ! 124: ! 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: { ! 334: register struct type *type; ! 335: ! 336: COERCE_ENUM (arg1); ! 337: ! 338: type = VALUE_TYPE (arg1); ! 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: { ! 352: COERCE_ENUM (arg1); ! 353: ! 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.