|
|
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:
1.1.1.3 ! root 30: value value_x_binop ();
! 31:
1.1 root 32: value
33: value_add (arg1, arg2)
34: value arg1, arg2;
35: {
36: register value val, valint, valptr;
37: register int len;
38:
39: COERCE_ARRAY (arg1);
40: COERCE_ARRAY (arg2);
41:
42: if ((TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR
43: || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_PTR)
44: &&
45: (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT
46: || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_INT))
47: /* Exactly one argument is a pointer, and one is an integer. */
48: {
49: if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR)
50: {
51: valptr = arg1;
52: valint = arg2;
53: }
54: else
55: {
56: valptr = arg2;
57: valint = arg1;
58: }
59: len = TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (valptr)));
60: if (len == 0) len = 1; /* For (void *) */
61: val = value_from_long (builtin_type_long,
62: value_as_long (valptr)
63: + (len * value_as_long (valint)));
64: VALUE_TYPE (val) = VALUE_TYPE (valptr);
65: return val;
66: }
67:
1.1.1.3 ! root 68: return value_x_binop (arg1, arg2, BINOP_ADD);
1.1 root 69: }
70:
71: value
72: value_sub (arg1, arg2)
73: value arg1, arg2;
74: {
75: register value val;
76:
77: COERCE_ARRAY (arg1);
78: COERCE_ARRAY (arg2);
79:
80: if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR
81: &&
82: TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_INT)
83: {
84: val = value_from_long (builtin_type_long,
85: value_as_long (arg1)
86: - TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) * value_as_long (arg2));
87: VALUE_TYPE (val) = VALUE_TYPE (arg1);
88: return val;
89: }
90:
91: if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR
92: &&
93: VALUE_TYPE (arg1) == VALUE_TYPE (arg2))
94: {
95: val = value_from_long (builtin_type_long,
96: (value_as_long (arg1) - value_as_long (arg2))
97: / TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))));
98: return val;
99: }
100:
1.1.1.3 ! root 101: return value_x_binop (arg1, arg2, BINOP_SUB);
1.1 root 102: }
103:
104: /* Return the value of ARRAY[IDX]. */
105:
106: value
107: value_subscript (array, idx)
108: value array, idx;
109: {
110: return value_ind (value_add (array, idx));
111: }
1.1.1.3 ! root 112:
! 113: /* Check to see if either argument is a structure. If so, then
! 114: create an argument vector that calls arg1.operator @ (arg1,arg2)
! 115: and return that value (where '@' is any binary operator which
! 116: is legal for GNU C++). If both args are scalar types then just
! 117: return value_binop(). */
! 118:
! 119: value
! 120: value_x_binop (arg1, arg2, op)
! 121: value arg1, arg2;
! 122: int op;
! 123: {
! 124: value * argvec;
! 125: char *ptr;
! 126: char tstr[13];
! 127:
! 128: COERCE_ENUM (arg1);
! 129: COERCE_ENUM (arg2);
! 130:
! 131: if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT
! 132: || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_STRUCT)
! 133: {
! 134: /* now we know that what we have to do is construct our
! 135: arg vector and find the right function to call it with. */
! 136:
! 137: if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT)
! 138: error ("friend functions not implemented yet");
1.1 root 139:
1.1.1.3 ! root 140: argvec = (value *) alloca (sizeof (value) * 4);
! 141: argvec[1] = value_addr (arg1);
! 142: argvec[2] = arg2;
! 143: argvec[3] = 0;
! 144:
! 145: /* make the right function name up */
! 146: strcpy(tstr,"operator __");
! 147: ptr = tstr+9;
! 148: switch (op)
! 149: {
! 150: case BINOP_ADD: *ptr++ = '+'; *ptr = '\0'; break;
! 151: case BINOP_SUB: *ptr++ = '-'; *ptr = '\0'; break;
! 152: case BINOP_MUL: *ptr++ = '*'; *ptr = '\0'; break;
! 153: case BINOP_DIV: *ptr++ = '/'; *ptr = '\0'; break;
! 154: case BINOP_REM: *ptr++ = '%'; *ptr = '\0';break;
! 155: case BINOP_LSH: *ptr++ = '<'; *ptr = '<'; break;
! 156: case BINOP_RSH: *ptr++ = '>'; *ptr = '>'; break;
! 157: case BINOP_LOGAND: *ptr++ = '&'; *ptr = '\0'; break;
! 158: case BINOP_LOGIOR: *ptr++ = '|'; *ptr = '\0'; break;
! 159: case BINOP_LOGXOR: *ptr++ = '^'; *ptr = '\0'; break;
! 160: case BINOP_AND: *ptr++ = '&'; *ptr = '&'; break;
! 161: case BINOP_OR: *ptr++ = '|'; *ptr = '|'; break;
! 162: case BINOP_MIN: *ptr++ = '<'; *ptr = '?'; break;
! 163: case BINOP_MAX: *ptr++ = '>'; *ptr = '?'; break;
! 164: default:
! 165: error ("Invalid binary operation specified.");
! 166: }
! 167: argvec[0] = value_struct_elt (arg1, argvec+1, tstr, "structure");
! 168: if (argvec[0])
! 169: return call_function (argvec[0], 2, argvec + 1);
! 170: else error ("member function %s not found", tstr);
! 171: }
! 172:
! 173: return value_binop(arg1, arg2, op);
! 174: }
! 175:
1.1 root 176: /* Perform a binary operation on two integers or two floats.
177: Does not support addition and subtraction on pointers;
178: use value_add or value_sub if you want to handle those possibilities. */
179:
180: value
181: value_binop (arg1, arg2, op)
182: value arg1, arg2;
183: int op;
184: {
185: register value val;
186:
1.1.1.2 root 187: COERCE_ENUM (arg1);
188: COERCE_ENUM (arg2);
189:
1.1 root 190: if ((TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_FLT
191: &&
192: TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT)
193: ||
194: (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_FLT
195: &&
196: TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_INT))
197: error ("Argument to arithmetic operation not a number.");
198:
199: if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_FLT
200: ||
201: TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_FLT)
202: {
203: double v1, v2, v;
204: v1 = value_as_double (arg1);
205: v2 = value_as_double (arg2);
206: switch (op)
207: {
208: case BINOP_ADD:
209: v = v1 + v2;
210: break;
211:
212: case BINOP_SUB:
213: v = v1 - v2;
214: break;
215:
216: case BINOP_MUL:
217: v = v1 * v2;
218: break;
219:
220: case BINOP_DIV:
221: v = v1 / v2;
222: break;
223:
224: default:
225: error ("Integer-only operation on floating point number.");
226: }
227:
228: val = allocate_value (builtin_type_double);
229: *(double *) VALUE_CONTENTS (val) = v;
230: }
231: else
232: {
233: long v1, v2, v;
234: v1 = value_as_long (arg1);
235: v2 = value_as_long (arg2);
236:
237: switch (op)
238: {
239: case BINOP_ADD:
240: v = v1 + v2;
241: break;
242:
243: case BINOP_SUB:
244: v = v1 - v2;
245: break;
246:
247: case BINOP_MUL:
248: v = v1 * v2;
249: break;
250:
251: case BINOP_DIV:
252: v = v1 / v2;
253: break;
254:
255: case BINOP_REM:
256: v = v1 % v2;
257: break;
258:
259: case BINOP_LSH:
260: v = v1 << v2;
261: break;
262:
263: case BINOP_RSH:
264: v = v1 >> v2;
265: break;
266:
267: case BINOP_LOGAND:
268: v = v1 & v2;
269: break;
270:
271: case BINOP_LOGIOR:
272: v = v1 | v2;
273: break;
274:
275: case BINOP_LOGXOR:
276: v = v1 ^ v2;
277: break;
278:
279: case BINOP_AND:
280: v = v1 && v2;
281: break;
282:
283: case BINOP_OR:
284: v = v1 || v2;
285: break;
286:
1.1.1.3 ! root 287: case BINOP_MIN:
! 288: v = v1 < v2 ? v1 : v2;
! 289: break;
! 290:
! 291: case BINOP_MAX:
! 292: v = v1 > v2 ? v1 : v2;
! 293: break;
! 294:
1.1 root 295: default:
296: error ("Invalid binary operation on numbers.");
297: }
298:
299: val = allocate_value (builtin_type_long);
300: *(long *) VALUE_CONTENTS (val) = v;
301: }
302:
303: return val;
304: }
305:
306: /* Simulate the C operator ! -- return 1 if ARG1 contains zeros. */
307:
308: int
309: value_zerop (arg1)
310: value arg1;
311: {
312: register int len;
313: register char *p;
314:
315: COERCE_ARRAY (arg1);
316:
317: len = TYPE_LENGTH (VALUE_TYPE (arg1));
318: p = VALUE_CONTENTS (arg1);
319:
320: while (--len >= 0)
321: {
322: if (*p++)
323: break;
324: }
325:
326: return len < 0;
327: }
328:
329: /* Simulate the C operator == by returning a 1
330: iff ARG1 and ARG2 have equal contents. */
331:
332: int
333: value_equal (arg1, arg2)
334: register value arg1, arg2;
335:
336: {
337: register int len;
338: register char *p1, *p2;
339: enum type_code code1;
340: enum type_code code2;
341:
342: COERCE_ARRAY (arg1);
343: COERCE_ARRAY (arg2);
344:
345: code1 = TYPE_CODE (VALUE_TYPE (arg1));
346: code2 = TYPE_CODE (VALUE_TYPE (arg2));
347:
348: if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
349: return value_as_long (arg1) == value_as_long (arg2);
350: else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
351: && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
352: return value_as_double (arg1) == value_as_double (arg2);
353: else if ((code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_INT)
354: || (code2 == TYPE_CODE_PTR && code1 == TYPE_CODE_INT))
355: return value_as_long (arg1) == value_as_long (arg2);
356: else if (code1 == code2
357: && ((len = TYPE_LENGTH (VALUE_TYPE (arg1)))
358: == TYPE_LENGTH (VALUE_TYPE (arg2))))
359: {
360: p1 = VALUE_CONTENTS (arg1);
361: p2 = VALUE_CONTENTS (arg2);
362: while (--len >= 0)
363: {
364: if (*p1++ != *p2++)
365: break;
366: }
367: return len < 0;
368: }
369: else
370: error ("Invalid type combination in equality test.");
371: }
372:
373: /* Simulate the C operator < by returning 1
374: iff ARG1's contents are less than ARG2's. */
375:
376: int
377: value_less (arg1, arg2)
378: register value arg1, arg2;
379: {
380: register enum type_code code1;
381: register enum type_code code2;
382:
383: COERCE_ARRAY (arg1);
384: COERCE_ARRAY (arg2);
385:
386: code1 = TYPE_CODE (VALUE_TYPE (arg1));
387: code2 = TYPE_CODE (VALUE_TYPE (arg2));
388:
389: if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
390: return value_as_long (arg1) < value_as_long (arg2);
391: else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
392: && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
393: return value_as_double (arg1) < value_as_double (arg2);
394: else if ((code1 == TYPE_CODE_PTR || code1 == TYPE_CODE_INT)
395: && (code2 == TYPE_CODE_PTR || code2 == TYPE_CODE_INT))
396: return value_as_long (arg1) < value_as_long (arg2);
397: else
398: error ("Invalid type combination in ordering comparison.");
399: }
400:
401: /* The unary operators - and ~. Both free the argument ARG1. */
402:
403: value
404: value_neg (arg1)
405: register value arg1;
406: {
1.1.1.2 root 407: register struct type *type;
408:
409: COERCE_ENUM (arg1);
410:
411: type = VALUE_TYPE (arg1);
1.1 root 412:
413: if (TYPE_CODE (type) == TYPE_CODE_FLT)
414: return value_from_double (type, - value_as_double (arg1));
415: else if (TYPE_CODE (type) == TYPE_CODE_INT)
416: return value_from_long (type, - value_as_long (arg1));
417: else
418: error ("Argument to negate operation not a number.");
419: }
420:
421: value
422: value_lognot (arg1)
423: register value arg1;
424: {
1.1.1.2 root 425: COERCE_ENUM (arg1);
426:
1.1 root 427: if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT)
428: error ("Argument to complement operation not an integer.");
429:
430: return value_from_long (VALUE_TYPE (arg1), ~ value_as_long (arg1));
431: }
432:
433: static
434: initialize ()
435: {
436: }
437:
438: END_FILE
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.