Fixed bug printing 29050 instructions.
[deliverable/binutils-gdb.git] / gdb / valarith.c
1 /* Perform arithmetic and other operations on values, for GDB.
2 Copyright (C) 1986, 1989 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 GDB is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
9 any later version.
10
11 GDB is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GDB; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include "defs.h"
21 #include "param.h"
22 #include "value.h"
23 #include "expression.h"
24 #include "target.h"
25 #include <string.h>
26
27 \f
28 value value_x_binop ();
29 value value_subscripted_rvalue ();
30
31 value
32 value_add (arg1, arg2)
33 value arg1, arg2;
34 {
35 register value val, valint, valptr;
36 register int len;
37
38 COERCE_ARRAY (arg1);
39 COERCE_ARRAY (arg2);
40
41 if ((TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR
42 || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_PTR)
43 &&
44 (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT
45 || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_INT))
46 /* Exactly one argument is a pointer, and one is an integer. */
47 {
48 if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR)
49 {
50 valptr = arg1;
51 valint = arg2;
52 }
53 else
54 {
55 valptr = arg2;
56 valint = arg1;
57 }
58 len = TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (valptr)));
59 if (len == 0) len = 1; /* For (void *) */
60 val = value_from_long (builtin_type_long,
61 value_as_long (valptr)
62 + (len * value_as_long (valint)));
63 VALUE_TYPE (val) = VALUE_TYPE (valptr);
64 return val;
65 }
66
67 return value_binop (arg1, arg2, BINOP_ADD);
68 }
69
70 value
71 value_sub (arg1, arg2)
72 value arg1, arg2;
73 {
74 register value val;
75
76 COERCE_ARRAY (arg1);
77 COERCE_ARRAY (arg2);
78
79 if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR)
80 {
81 if (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_INT)
82 {
83 /* pointer - integer. */
84 val = value_from_long
85 (builtin_type_long,
86 value_as_long (arg1)
87 - (TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)))
88 * value_as_long (arg2)));
89 VALUE_TYPE (val) = VALUE_TYPE (arg1);
90 return val;
91 }
92 else if (VALUE_TYPE (arg1) == VALUE_TYPE (arg2))
93 {
94 /* pointer to <type x> - pointer to <type x>. */
95 val = value_from_long
96 (builtin_type_long,
97 (value_as_long (arg1) - value_as_long (arg2))
98 / TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))));
99 return val;
100 }
101 else
102 {
103 error ("\
104 First argument of `-' is a pointer and second argument is neither\n\
105 an integer nor a pointer of the same type.");
106 }
107 }
108
109 return value_binop (arg1, arg2, BINOP_SUB);
110 }
111
112 /* Return the value of ARRAY[IDX]. */
113
114 value
115 value_subscript (array, idx)
116 value array, idx;
117 {
118 if (TYPE_CODE (VALUE_TYPE (array)) == TYPE_CODE_ARRAY
119 && VALUE_LVAL (array) != lval_memory)
120 return value_subscripted_rvalue (array, idx);
121 else
122 return value_ind (value_add (array, idx));
123 }
124
125 /* Return the value of EXPR[IDX], expr an aggregate rvalue
126 (eg, a vector register). This routine used to promote floats
127 to doubles, but no longer does. */
128
129 value
130 value_subscripted_rvalue (array, idx)
131 value array, idx;
132 {
133 struct type *elt_type = TYPE_TARGET_TYPE (VALUE_TYPE (array));
134 int elt_size = TYPE_LENGTH (elt_type);
135 int elt_offs = elt_size * value_as_long (idx);
136 value v;
137
138 if (elt_offs >= TYPE_LENGTH (VALUE_TYPE (array)))
139 error ("no such vector element");
140
141 v = allocate_value (elt_type);
142 bcopy (VALUE_CONTENTS (array) + elt_offs, VALUE_CONTENTS (v), elt_size);
143
144 if (VALUE_LVAL (array) == lval_internalvar)
145 VALUE_LVAL (v) = lval_internalvar_component;
146 else
147 VALUE_LVAL (v) = not_lval;
148 VALUE_ADDRESS (v) = VALUE_ADDRESS (array);
149 VALUE_OFFSET (v) = VALUE_OFFSET (array) + elt_offs;
150 VALUE_BITSIZE (v) = elt_size * 8;
151 return v;
152 }
153 \f
154 /* Check to see if either argument is a structure. This is called so
155 we know whether to go ahead with the normal binop or look for a
156 user defined function instead.
157
158 For now, we do not overload the `=' operator. */
159
160 int
161 binop_user_defined_p (op, arg1, arg2)
162 enum exp_opcode op;
163 value arg1, arg2;
164 {
165 if (op == BINOP_ASSIGN)
166 return 0;
167 return (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT
168 || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_STRUCT
169 || (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF
170 && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_STRUCT)
171 || (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_REF
172 && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) == TYPE_CODE_STRUCT));
173 }
174
175 /* Check to see if argument is a structure. This is called so
176 we know whether to go ahead with the normal unop or look for a
177 user defined function instead.
178
179 For now, we do not overload the `&' operator. */
180
181 int unop_user_defined_p (op, arg1)
182 enum exp_opcode op;
183 value arg1;
184 {
185 if (op == UNOP_ADDR)
186 return 0;
187 return (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT
188 || (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF
189 && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_STRUCT));
190 }
191
192 /* We know either arg1 or arg2 is a structure, so try to find the right
193 user defined function. Create an argument vector that calls
194 arg1.operator @ (arg1,arg2) and return that value (where '@' is any
195 binary operator which is legal for GNU C++). */
196
197 value
198 value_x_binop (arg1, arg2, op, otherop)
199 value arg1, arg2;
200 enum exp_opcode op, otherop;
201 {
202 value * argvec;
203 char *ptr;
204 char tstr[13];
205 int static_memfuncp;
206
207 COERCE_ENUM (arg1);
208 COERCE_ENUM (arg2);
209
210 /* now we know that what we have to do is construct our
211 arg vector and find the right function to call it with. */
212
213 if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT)
214 error ("Can't do that binary op on that type"); /* FIXME be explicit */
215
216 argvec = (value *) alloca (sizeof (value) * 4);
217 argvec[1] = value_addr (arg1);
218 argvec[2] = arg2;
219 argvec[3] = 0;
220
221 /* make the right function name up */
222 strcpy(tstr, "operator__");
223 ptr = tstr+8;
224 switch (op)
225 {
226 case BINOP_ADD: strcpy(ptr,"+"); break;
227 case BINOP_SUB: strcpy(ptr,"-"); break;
228 case BINOP_MUL: strcpy(ptr,"*"); break;
229 case BINOP_DIV: strcpy(ptr,"/"); break;
230 case BINOP_REM: strcpy(ptr,"%"); break;
231 case BINOP_LSH: strcpy(ptr,"<<"); break;
232 case BINOP_RSH: strcpy(ptr,">>"); break;
233 case BINOP_LOGAND: strcpy(ptr,"&"); break;
234 case BINOP_LOGIOR: strcpy(ptr,"|"); break;
235 case BINOP_LOGXOR: strcpy(ptr,"^"); break;
236 case BINOP_AND: strcpy(ptr,"&&"); break;
237 case BINOP_OR: strcpy(ptr,"||"); break;
238 case BINOP_MIN: strcpy(ptr,"<?"); break;
239 case BINOP_MAX: strcpy(ptr,">?"); break;
240 case BINOP_ASSIGN: strcpy(ptr,"="); break;
241 case BINOP_ASSIGN_MODIFY:
242 switch (otherop)
243 {
244 case BINOP_ADD: strcpy(ptr,"+="); break;
245 case BINOP_SUB: strcpy(ptr,"-="); break;
246 case BINOP_MUL: strcpy(ptr,"*="); break;
247 case BINOP_DIV: strcpy(ptr,"/="); break;
248 case BINOP_REM: strcpy(ptr,"%="); break;
249 case BINOP_LOGAND: strcpy(ptr,"&="); break;
250 case BINOP_LOGIOR: strcpy(ptr,"|="); break;
251 case BINOP_LOGXOR: strcpy(ptr,"^="); break;
252 default:
253 error ("Invalid binary operation specified.");
254 }
255 break;
256 case BINOP_SUBSCRIPT: strcpy(ptr,"[]"); break;
257 case BINOP_EQUAL: strcpy(ptr,"=="); break;
258 case BINOP_NOTEQUAL: strcpy(ptr,"!="); break;
259 case BINOP_LESS: strcpy(ptr,"<"); break;
260 case BINOP_GTR: strcpy(ptr,">"); break;
261 case BINOP_GEQ: strcpy(ptr,">="); break;
262 case BINOP_LEQ: strcpy(ptr,"<="); break;
263 default:
264 error ("Invalid binary operation specified.");
265 }
266 argvec[0] = value_struct_elt (&arg1, argvec+1, tstr, &static_memfuncp, "structure");
267 if (argvec[0])
268 {
269 if (static_memfuncp)
270 {
271 argvec[1] = argvec[0];
272 argvec++;
273 }
274 return target_call_function (argvec[0], 2 - static_memfuncp, argvec + 1);
275 }
276 error ("member function %s not found", tstr);
277 #ifdef lint
278 return target_call_function (argvec[0], 2 - static_memfuncp, argvec + 1);
279 #endif
280 }
281
282 /* We know that arg1 is a structure, so try to find a unary user
283 defined operator that matches the operator in question.
284 Create an argument vector that calls arg1.operator @ (arg1)
285 and return that value (where '@' is (almost) any unary operator which
286 is legal for GNU C++). */
287
288 value
289 value_x_unop (arg1, op)
290 value arg1;
291 enum exp_opcode op;
292 {
293 value * argvec;
294 char *ptr;
295 char tstr[13];
296 int static_memfuncp;
297
298 COERCE_ENUM (arg1);
299
300 /* now we know that what we have to do is construct our
301 arg vector and find the right function to call it with. */
302
303 if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT)
304 error ("Can't do that unary op on that type"); /* FIXME be explicit */
305
306 argvec = (value *) alloca (sizeof (value) * 3);
307 argvec[1] = value_addr (arg1);
308 argvec[2] = 0;
309
310 /* make the right function name up */
311 strcpy(tstr,"operator__");
312 ptr = tstr+8;
313 switch (op)
314 {
315 case UNOP_PREINCREMENT: strcpy(ptr,"++"); break;
316 case UNOP_PREDECREMENT: strcpy(ptr,"++"); break;
317 case UNOP_POSTINCREMENT: strcpy(ptr,"++"); break;
318 case UNOP_POSTDECREMENT: strcpy(ptr,"++"); break;
319 case UNOP_ZEROP: strcpy(ptr,"!"); break;
320 case UNOP_LOGNOT: strcpy(ptr,"~"); break;
321 case UNOP_NEG: strcpy(ptr,"-"); break;
322 default:
323 error ("Invalid binary operation specified.");
324 }
325 argvec[0] = value_struct_elt (&arg1, argvec+1, tstr, &static_memfuncp, "structure");
326 if (argvec[0])
327 {
328 if (static_memfuncp)
329 {
330 argvec[1] = argvec[0];
331 argvec++;
332 }
333 return target_call_function (argvec[0], 1 - static_memfuncp, argvec + 1);
334 }
335 error ("member function %s not found", tstr);
336 return 0; /* For lint -- never reached */
337 }
338 \f
339 /* Perform a binary operation on two integers or two floats.
340 Does not support addition and subtraction on pointers;
341 use value_add or value_sub if you want to handle those possibilities. */
342
343 value
344 value_binop (arg1, arg2, op)
345 value arg1, arg2;
346 int op;
347 {
348 register value val;
349
350 COERCE_ENUM (arg1);
351 COERCE_ENUM (arg2);
352
353 if ((TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_FLT
354 &&
355 TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT)
356 ||
357 (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_FLT
358 &&
359 TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_INT))
360 error ("Argument to arithmetic operation not a number.");
361
362 if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_FLT
363 ||
364 TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_FLT)
365 {
366 double v1, v2, v;
367 v1 = value_as_double (arg1);
368 v2 = value_as_double (arg2);
369 switch (op)
370 {
371 case BINOP_ADD:
372 v = v1 + v2;
373 break;
374
375 case BINOP_SUB:
376 v = v1 - v2;
377 break;
378
379 case BINOP_MUL:
380 v = v1 * v2;
381 break;
382
383 case BINOP_DIV:
384 v = v1 / v2;
385 break;
386
387 default:
388 error ("Integer-only operation on floating point number.");
389 }
390
391 val = allocate_value (builtin_type_double);
392 SWAP_TARGET_AND_HOST (&v, sizeof (v));
393 *(double *) VALUE_CONTENTS_RAW (val) = v;
394 }
395 else
396 /* Integral operations here. */
397 {
398 /* Should we promote to unsigned longest? */
399 if ((TYPE_UNSIGNED (VALUE_TYPE (arg1))
400 || TYPE_UNSIGNED (VALUE_TYPE (arg2)))
401 && (TYPE_LENGTH (VALUE_TYPE (arg1)) >= sizeof (unsigned LONGEST)
402 || TYPE_LENGTH (VALUE_TYPE (arg1)) >= sizeof (unsigned LONGEST)))
403 {
404 unsigned LONGEST v1, v2, v;
405 v1 = (unsigned LONGEST) value_as_long (arg1);
406 v2 = (unsigned LONGEST) value_as_long (arg2);
407
408 switch (op)
409 {
410 case BINOP_ADD:
411 v = v1 + v2;
412 break;
413
414 case BINOP_SUB:
415 v = v1 - v2;
416 break;
417
418 case BINOP_MUL:
419 v = v1 * v2;
420 break;
421
422 case BINOP_DIV:
423 v = v1 / v2;
424 break;
425
426 case BINOP_REM:
427 v = v1 % v2;
428 break;
429
430 case BINOP_LSH:
431 v = v1 << v2;
432 break;
433
434 case BINOP_RSH:
435 v = v1 >> v2;
436 break;
437
438 case BINOP_LOGAND:
439 v = v1 & v2;
440 break;
441
442 case BINOP_LOGIOR:
443 v = v1 | v2;
444 break;
445
446 case BINOP_LOGXOR:
447 v = v1 ^ v2;
448 break;
449
450 case BINOP_AND:
451 v = v1 && v2;
452 break;
453
454 case BINOP_OR:
455 v = v1 || v2;
456 break;
457
458 case BINOP_MIN:
459 v = v1 < v2 ? v1 : v2;
460 break;
461
462 case BINOP_MAX:
463 v = v1 > v2 ? v1 : v2;
464 break;
465
466 default:
467 error ("Invalid binary operation on numbers.");
468 }
469
470 val = allocate_value (BUILTIN_TYPE_UNSIGNED_LONGEST);
471 SWAP_TARGET_AND_HOST (&v, sizeof (v));
472 *(unsigned LONGEST *) VALUE_CONTENTS_RAW (val) = v;
473 }
474 else
475 {
476 LONGEST v1, v2, v;
477 v1 = value_as_long (arg1);
478 v2 = value_as_long (arg2);
479
480 switch (op)
481 {
482 case BINOP_ADD:
483 v = v1 + v2;
484 break;
485
486 case BINOP_SUB:
487 v = v1 - v2;
488 break;
489
490 case BINOP_MUL:
491 v = v1 * v2;
492 break;
493
494 case BINOP_DIV:
495 v = v1 / v2;
496 break;
497
498 case BINOP_REM:
499 v = v1 % v2;
500 break;
501
502 case BINOP_LSH:
503 v = v1 << v2;
504 break;
505
506 case BINOP_RSH:
507 v = v1 >> v2;
508 break;
509
510 case BINOP_LOGAND:
511 v = v1 & v2;
512 break;
513
514 case BINOP_LOGIOR:
515 v = v1 | v2;
516 break;
517
518 case BINOP_LOGXOR:
519 v = v1 ^ v2;
520 break;
521
522 case BINOP_AND:
523 v = v1 && v2;
524 break;
525
526 case BINOP_OR:
527 v = v1 || v2;
528 break;
529
530 case BINOP_MIN:
531 v = v1 < v2 ? v1 : v2;
532 break;
533
534 case BINOP_MAX:
535 v = v1 > v2 ? v1 : v2;
536 break;
537
538 default:
539 error ("Invalid binary operation on numbers.");
540 }
541
542 val = allocate_value (BUILTIN_TYPE_LONGEST);
543 SWAP_TARGET_AND_HOST (&v, sizeof (v));
544 *(LONGEST *) VALUE_CONTENTS_RAW (val) = v;
545 }
546 }
547
548 return val;
549 }
550 \f
551 /* Simulate the C operator ! -- return 1 if ARG1 contains zeros. */
552
553 int
554 value_zerop (arg1)
555 value arg1;
556 {
557 register int len;
558 register char *p;
559
560 COERCE_ARRAY (arg1);
561
562 len = TYPE_LENGTH (VALUE_TYPE (arg1));
563 p = VALUE_CONTENTS (arg1);
564
565 while (--len >= 0)
566 {
567 if (*p++)
568 break;
569 }
570
571 return len < 0;
572 }
573
574 /* Simulate the C operator == by returning a 1
575 iff ARG1 and ARG2 have equal contents. */
576
577 int
578 value_equal (arg1, arg2)
579 register value arg1, arg2;
580
581 {
582 register int len;
583 register char *p1, *p2;
584 enum type_code code1;
585 enum type_code code2;
586
587 COERCE_ARRAY (arg1);
588 COERCE_ARRAY (arg2);
589
590 code1 = TYPE_CODE (VALUE_TYPE (arg1));
591 code2 = TYPE_CODE (VALUE_TYPE (arg2));
592
593 if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
594 return value_as_long (arg1) == value_as_long (arg2);
595 else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
596 && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
597 return value_as_double (arg1) == value_as_double (arg2);
598 else if ((code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_INT)
599 || (code2 == TYPE_CODE_PTR && code1 == TYPE_CODE_INT))
600 return (char *) value_as_long (arg1) == (char *) value_as_long (arg2);
601 else if (code1 == code2
602 && ((len = TYPE_LENGTH (VALUE_TYPE (arg1)))
603 == TYPE_LENGTH (VALUE_TYPE (arg2))))
604 {
605 p1 = VALUE_CONTENTS (arg1);
606 p2 = VALUE_CONTENTS (arg2);
607 while (--len >= 0)
608 {
609 if (*p1++ != *p2++)
610 break;
611 }
612 return len < 0;
613 }
614 else
615 {
616 error ("Invalid type combination in equality test.");
617 return 0; /* For lint -- never reached */
618 }
619 }
620
621 /* Simulate the C operator < by returning 1
622 iff ARG1's contents are less than ARG2's. */
623
624 int
625 value_less (arg1, arg2)
626 register value arg1, arg2;
627 {
628 register enum type_code code1;
629 register enum type_code code2;
630
631 COERCE_ARRAY (arg1);
632 COERCE_ARRAY (arg2);
633
634 code1 = TYPE_CODE (VALUE_TYPE (arg1));
635 code2 = TYPE_CODE (VALUE_TYPE (arg2));
636
637 if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
638 {
639 if (TYPE_UNSIGNED (VALUE_TYPE (arg1))
640 || TYPE_UNSIGNED (VALUE_TYPE (arg2)))
641 return (unsigned)value_as_long (arg1) < (unsigned)value_as_long (arg2);
642 else
643 return value_as_long (arg1) < value_as_long (arg2);
644 }
645 else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
646 && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
647 return value_as_double (arg1) < value_as_double (arg2);
648 else if ((code1 == TYPE_CODE_PTR || code1 == TYPE_CODE_INT)
649 && (code2 == TYPE_CODE_PTR || code2 == TYPE_CODE_INT))
650 {
651 /* FIXME, this assumes that host and target char *'s are the same! */
652 return (char *) value_as_long (arg1) < (char *) value_as_long (arg2);
653 }
654 else
655 {
656 error ("Invalid type combination in ordering comparison.");
657 return 0;
658 }
659 }
660 \f
661 /* The unary operators - and ~. Both free the argument ARG1. */
662
663 value
664 value_neg (arg1)
665 register value arg1;
666 {
667 register struct type *type;
668
669 COERCE_ENUM (arg1);
670
671 type = VALUE_TYPE (arg1);
672
673 if (TYPE_CODE (type) == TYPE_CODE_FLT)
674 return value_from_double (type, - value_as_double (arg1));
675 else if (TYPE_CODE (type) == TYPE_CODE_INT)
676 return value_from_long (type, - value_as_long (arg1));
677 else {
678 error ("Argument to negate operation not a number.");
679 return 0; /* For lint -- never reached */
680 }
681 }
682
683 value
684 value_lognot (arg1)
685 register value arg1;
686 {
687 COERCE_ENUM (arg1);
688
689 if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT)
690 error ("Argument to complement operation not an integer.");
691
692 return value_from_long (VALUE_TYPE (arg1), ~ value_as_long (arg1));
693 }
694 \f
This page took 0.042659 seconds and 4 git commands to generate.