|
|
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:
1.1.1.4 root 66: return value_binop (arg1, arg2, BINOP_ADD);
1.1 root 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:
1.1.1.4 root 99: return value_binop (arg1, arg2, BINOP_SUB);
1.1 root 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: }
1.1.1.4 root 110:
1.1 root 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:
1.1.1.2 root 122: COERCE_ENUM (arg1);
123: COERCE_ENUM (arg2);
124:
1.1 root 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: {
1.1.1.2 root 334: register struct type *type;
335:
336: COERCE_ENUM (arg1);
337:
338: type = VALUE_TYPE (arg1);
1.1 root 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: {
1.1.1.2 root 352: COERCE_ENUM (arg1);
353:
1.1 root 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.