gdb-2.5.2
[deliverable/binutils-gdb.git] / gdb / valarith.c
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 \f
30 value value_x_binop ();
31
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
68 return value_x_binop (arg1, arg2, BINOP_ADD);
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
101 return value_x_binop (arg1, arg2, BINOP_SUB);
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 }
112 \f
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");
139
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 \f
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
187 COERCE_ENUM (arg1);
188 COERCE_ENUM (arg2);
189
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
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
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 \f
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 \f
401 /* The unary operators - and ~. Both free the argument ARG1. */
402
403 value
404 value_neg (arg1)
405 register value arg1;
406 {
407 register struct type *type;
408
409 COERCE_ENUM (arg1);
410
411 type = VALUE_TYPE (arg1);
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 {
425 COERCE_ENUM (arg1);
426
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 \f
433 static
434 initialize ()
435 {
436 }
437
438 END_FILE
This page took 0.050605 seconds and 5 git commands to generate.