|
|
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.