|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.