772e59069991797c00de7d06a2cf8cddf17aae54
[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 "param.h"
23 #include "symtab.h"
24 #include "value.h"
25 #include "expression.h"
26
27 \f
28 value value_x_binop ();
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 \f
111 /* Check to see if either argument is a structure. This is called so
112 we know whether to go ahead with the normal binop or look for a
113 user defined function instead.
114
115 For now, we do not overload the `=' operator. */
116
117 int
118 binop_user_defined_p (op, arg1, arg2)
119 enum exp_opcode op;
120 value arg1, arg2;
121 {
122 if (op == BINOP_ASSIGN)
123 return 0;
124 return (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT
125 || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_STRUCT
126 || (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF
127 && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_STRUCT)
128 || (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_REF
129 && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) == TYPE_CODE_STRUCT));
130 }
131
132 /* Check to see if argument is a structure. This is called so
133 we know whether to go ahead with the normal unop or look for a
134 user defined function instead.
135
136 For now, we do not overload the `&' operator. */
137
138 int unop_user_defined_p (op, arg1)
139 enum exp_opcode op;
140 value arg1;
141 {
142 if (op == UNOP_ADDR)
143 return 0;
144 return (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT
145 || (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF
146 && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_STRUCT));
147 }
148
149 /* We know either arg1 or arg2 is a structure, so try to find the right
150 user defined function. Create an argument vector that calls
151 arg1.operator @ (arg1,arg2) and return that value (where '@' is any
152 binary operator which is legal for GNU C++). */
153
154 value
155 value_x_binop (arg1, arg2, op, otherop)
156 value arg1, arg2;
157 int op, otherop;
158 {
159 value * argvec;
160 char *ptr;
161 char tstr[13];
162
163 COERCE_ENUM (arg1);
164 COERCE_ENUM (arg2);
165
166 /* now we know that what we have to do is construct our
167 arg vector and find the right function to call it with. */
168
169 if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT)
170 error ("friend functions not implemented yet");
171
172 argvec = (value *) alloca (sizeof (value) * 4);
173 argvec[1] = value_addr (arg1);
174 argvec[2] = arg2;
175 argvec[3] = 0;
176
177 /* make the right function name up */
178 strcpy(tstr, "operator __");
179 ptr = tstr+9;
180 switch (op)
181 {
182 case BINOP_ADD: strcpy(ptr,"+"); break;
183 case BINOP_SUB: strcpy(ptr,"-"); break;
184 case BINOP_MUL: strcpy(ptr,"*"); break;
185 case BINOP_DIV: strcpy(ptr,"/"); break;
186 case BINOP_REM: strcpy(ptr,"%"); break;
187 case BINOP_LSH: strcpy(ptr,"<<"); break;
188 case BINOP_RSH: strcpy(ptr,">>"); break;
189 case BINOP_LOGAND: strcpy(ptr,"&"); break;
190 case BINOP_LOGIOR: strcpy(ptr,"|"); break;
191 case BINOP_LOGXOR: strcpy(ptr,"^"); break;
192 case BINOP_AND: strcpy(ptr,"&&"); break;
193 case BINOP_OR: strcpy(ptr,"||"); break;
194 case BINOP_MIN: strcpy(ptr,"<?"); break;
195 case BINOP_MAX: strcpy(ptr,">?"); break;
196 case BINOP_ASSIGN: strcpy(ptr,"="); break;
197 case BINOP_ASSIGN_MODIFY:
198 switch (otherop)
199 {
200 case BINOP_ADD: strcpy(ptr,"+="); break;
201 case BINOP_SUB: strcpy(ptr,"-="); break;
202 case BINOP_MUL: strcpy(ptr,"*="); break;
203 case BINOP_DIV: strcpy(ptr,"/="); break;
204 case BINOP_REM: strcpy(ptr,"%="); break;
205 case BINOP_LOGAND: strcpy(ptr,"&="); break;
206 case BINOP_LOGIOR: strcpy(ptr,"|="); break;
207 case BINOP_LOGXOR: strcpy(ptr,"^="); break;
208 default:
209 error ("Invalid binary operation specified.");
210 }
211 break;
212 case BINOP_SUBSCRIPT: strcpy(ptr,"[]"); break;
213 case BINOP_EQUAL: strcpy(ptr,"=="); break;
214 case BINOP_NOTEQUAL: strcpy(ptr,"!="); break;
215 case BINOP_LESS: strcpy(ptr,"<"); break;
216 case BINOP_GTR: strcpy(ptr,">"); break;
217 case BINOP_GEQ: strcpy(ptr,">="); break;
218 case BINOP_LEQ: strcpy(ptr,"<="); break;
219 default:
220 error ("Invalid binary operation specified.");
221 }
222 argvec[0] = value_struct_elt (arg1, argvec+1, tstr, "structure");
223 if (argvec[0])
224 return call_function (argvec[0], 2, argvec + 1);
225 else error ("member function %s not found", tstr);
226 }
227
228 /* We know that arg1 is a structure, so try to find a unary user
229 defined operator that matches the operator in question.
230 Create an argument vector that calls arg1.operator @ (arg1)
231 and return that value (where '@' is (almost) any unary operator which
232 is legal for GNU C++). */
233
234 value
235 value_x_unop (arg1, op)
236 value arg1;
237 int op;
238 {
239 value * argvec;
240 char *ptr;
241 char tstr[13];
242
243 COERCE_ENUM (arg1);
244
245 /* now we know that what we have to do is construct our
246 arg vector and find the right function to call it with. */
247
248 if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT)
249 error ("friend functions not implemented yet");
250
251 argvec = (value *) alloca (sizeof (value) * 3);
252 argvec[1] = value_addr (arg1);
253 argvec[2] = 0;
254
255 /* make the right function name up */
256 strcpy(tstr,"operator __");
257 ptr = tstr+9;
258 switch (op)
259 {
260 case UNOP_PREINCREMENT: strcpy(ptr,"++"); break;
261 case UNOP_PREDECREMENT: strcpy(ptr,"++"); break;
262 case UNOP_POSTINCREMENT: strcpy(ptr,"++"); break;
263 case UNOP_POSTDECREMENT: strcpy(ptr,"++"); break;
264 case UNOP_ZEROP: strcpy(ptr,"!"); break;
265 case UNOP_LOGNOT: strcpy(ptr,"~"); break;
266 case UNOP_NEG: strcpy(ptr,"-"); break;
267 default:
268 error ("Invalid binary operation specified.");
269 }
270 argvec[0] = value_struct_elt (arg1, argvec+1, tstr, "structure");
271 if (argvec[0])
272 return call_function (argvec[0], 1, argvec + 1);
273 else error ("member function %s not found", tstr);
274 }
275 \f
276 /* Perform a binary operation on two integers or two floats.
277 Does not support addition and subtraction on pointers;
278 use value_add or value_sub if you want to handle those possibilities. */
279
280 value
281 value_binop (arg1, arg2, op)
282 value arg1, arg2;
283 int op;
284 {
285 register value val;
286
287 COERCE_ENUM (arg1);
288 COERCE_ENUM (arg2);
289
290 if ((TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_FLT
291 &&
292 TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT)
293 ||
294 (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_FLT
295 &&
296 TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_INT))
297 error ("Argument to arithmetic operation not a number.");
298
299 if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_FLT
300 ||
301 TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_FLT)
302 {
303 double v1, v2, v;
304 v1 = value_as_double (arg1);
305 v2 = value_as_double (arg2);
306 switch (op)
307 {
308 case BINOP_ADD:
309 v = v1 + v2;
310 break;
311
312 case BINOP_SUB:
313 v = v1 - v2;
314 break;
315
316 case BINOP_MUL:
317 v = v1 * v2;
318 break;
319
320 case BINOP_DIV:
321 v = v1 / v2;
322 break;
323
324 default:
325 error ("Integer-only operation on floating point number.");
326 }
327
328 val = allocate_value (builtin_type_double);
329 *(double *) VALUE_CONTENTS (val) = v;
330 }
331 else
332 {
333 LONGEST v1, v2, v;
334 v1 = value_as_long (arg1);
335 v2 = value_as_long (arg2);
336
337 switch (op)
338 {
339 case BINOP_ADD:
340 v = v1 + v2;
341 break;
342
343 case BINOP_SUB:
344 v = v1 - v2;
345 break;
346
347 case BINOP_MUL:
348 v = v1 * v2;
349 break;
350
351 case BINOP_DIV:
352 v = v1 / v2;
353 break;
354
355 case BINOP_REM:
356 v = v1 % v2;
357 break;
358
359 case BINOP_LSH:
360 v = v1 << v2;
361 break;
362
363 case BINOP_RSH:
364 v = v1 >> v2;
365 break;
366
367 case BINOP_LOGAND:
368 v = v1 & v2;
369 break;
370
371 case BINOP_LOGIOR:
372 v = v1 | v2;
373 break;
374
375 case BINOP_LOGXOR:
376 v = v1 ^ v2;
377 break;
378
379 case BINOP_AND:
380 v = v1 && v2;
381 break;
382
383 case BINOP_OR:
384 v = v1 || v2;
385 break;
386
387 case BINOP_MIN:
388 v = v1 < v2 ? v1 : v2;
389 break;
390
391 case BINOP_MAX:
392 v = v1 > v2 ? v1 : v2;
393 break;
394
395 default:
396 error ("Invalid binary operation on numbers.");
397 }
398
399 val = allocate_value (BUILTIN_TYPE_LONGEST);
400 *(LONGEST *) VALUE_CONTENTS (val) = v;
401 }
402
403 return val;
404 }
405 \f
406 /* Simulate the C operator ! -- return 1 if ARG1 contains zeros. */
407
408 int
409 value_zerop (arg1)
410 value arg1;
411 {
412 register int len;
413 register char *p;
414
415 COERCE_ARRAY (arg1);
416
417 len = TYPE_LENGTH (VALUE_TYPE (arg1));
418 p = VALUE_CONTENTS (arg1);
419
420 while (--len >= 0)
421 {
422 if (*p++)
423 break;
424 }
425
426 return len < 0;
427 }
428
429 /* Simulate the C operator == by returning a 1
430 iff ARG1 and ARG2 have equal contents. */
431
432 int
433 value_equal (arg1, arg2)
434 register value arg1, arg2;
435
436 {
437 register int len;
438 register char *p1, *p2;
439 enum type_code code1;
440 enum type_code code2;
441
442 COERCE_ARRAY (arg1);
443 COERCE_ARRAY (arg2);
444
445 code1 = TYPE_CODE (VALUE_TYPE (arg1));
446 code2 = TYPE_CODE (VALUE_TYPE (arg2));
447
448 if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
449 return value_as_long (arg1) == value_as_long (arg2);
450 else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
451 && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
452 return value_as_double (arg1) == value_as_double (arg2);
453 else if ((code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_INT)
454 || (code2 == TYPE_CODE_PTR && code1 == TYPE_CODE_INT))
455 return value_as_long (arg1) == value_as_long (arg2);
456 else if (code1 == code2
457 && ((len = TYPE_LENGTH (VALUE_TYPE (arg1)))
458 == TYPE_LENGTH (VALUE_TYPE (arg2))))
459 {
460 p1 = VALUE_CONTENTS (arg1);
461 p2 = VALUE_CONTENTS (arg2);
462 while (--len >= 0)
463 {
464 if (*p1++ != *p2++)
465 break;
466 }
467 return len < 0;
468 }
469 else
470 error ("Invalid type combination in equality test.");
471 }
472
473 /* Simulate the C operator < by returning 1
474 iff ARG1's contents are less than ARG2's. */
475
476 int
477 value_less (arg1, arg2)
478 register value arg1, arg2;
479 {
480 register enum type_code code1;
481 register enum type_code code2;
482
483 COERCE_ARRAY (arg1);
484 COERCE_ARRAY (arg2);
485
486 code1 = TYPE_CODE (VALUE_TYPE (arg1));
487 code2 = TYPE_CODE (VALUE_TYPE (arg2));
488
489 if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
490 return value_as_long (arg1) < value_as_long (arg2);
491 else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
492 && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
493 return value_as_double (arg1) < value_as_double (arg2);
494 else if ((code1 == TYPE_CODE_PTR || code1 == TYPE_CODE_INT)
495 && (code2 == TYPE_CODE_PTR || code2 == TYPE_CODE_INT))
496 return value_as_long (arg1) < value_as_long (arg2);
497 else
498 error ("Invalid type combination in ordering comparison.");
499 }
500 \f
501 /* The unary operators - and ~. Both free the argument ARG1. */
502
503 value
504 value_neg (arg1)
505 register value arg1;
506 {
507 register struct type *type;
508
509 COERCE_ENUM (arg1);
510
511 type = VALUE_TYPE (arg1);
512
513 if (TYPE_CODE (type) == TYPE_CODE_FLT)
514 return value_from_double (type, - value_as_double (arg1));
515 else if (TYPE_CODE (type) == TYPE_CODE_INT)
516 return value_from_long (type, - value_as_long (arg1));
517 else
518 error ("Argument to negate operation not a number.");
519 }
520
521 value
522 value_lognot (arg1)
523 register value arg1;
524 {
525 COERCE_ENUM (arg1);
526
527 if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT)
528 error ("Argument to complement operation not an integer.");
529
530 return value_from_long (VALUE_TYPE (arg1), ~ value_as_long (arg1));
531 }
532 \f
This page took 0.040646 seconds and 4 git commands to generate.