1 /* Perform arithmetic and other operations on values, for GDB.
2 Copyright 1986, 1989, 1991, 1992 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program 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 2 of the License, or
9 (at your option) any later version.
11 This program 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.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
24 #include "expression.h"
29 value_subscripted_rvalue
PARAMS ((value
, value
));
33 value_add (arg1
, arg2
)
36 register value valint
, valptr
;
42 if ((TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_PTR
43 || TYPE_CODE (VALUE_TYPE (arg2
)) == TYPE_CODE_PTR
)
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. */
49 if (TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_PTR
)
59 len
= TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (valptr
)));
60 if (len
== 0) len
= 1; /* For (void *) */
61 return value_from_longest (VALUE_TYPE (valptr
),
62 value_as_long (valptr
)
63 + (len
* value_as_long (valint
)));
66 return value_binop (arg1
, arg2
, BINOP_ADD
);
70 value_sub (arg1
, arg2
)
77 if (TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_PTR
)
79 if (TYPE_CODE (VALUE_TYPE (arg2
)) == TYPE_CODE_INT
)
81 /* pointer - integer. */
82 return value_from_longest
85 - (TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1
)))
86 * value_as_long (arg2
)));
88 else if (VALUE_TYPE (arg1
) == VALUE_TYPE (arg2
))
90 /* pointer to <type x> - pointer to <type x>. */
91 return value_from_longest
92 (builtin_type_long
, /* FIXME -- should be ptrdiff_t */
93 (value_as_long (arg1
) - value_as_long (arg2
))
94 / TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1
))));
99 First argument of `-' is a pointer and second argument is neither\n\
100 an integer nor a pointer of the same type.");
104 return value_binop (arg1
, arg2
, BINOP_SUB
);
107 /* Return the value of ARRAY[IDX]. */
110 value_subscript (array
, idx
)
113 if (TYPE_CODE (VALUE_TYPE (array
)) == TYPE_CODE_ARRAY
114 && VALUE_LVAL (array
) != lval_memory
)
115 return value_subscripted_rvalue (array
, idx
);
117 return value_ind (value_add (array
, idx
));
120 /* Return the value of EXPR[IDX], expr an aggregate rvalue
121 (eg, a vector register). This routine used to promote floats
122 to doubles, but no longer does. */
125 value_subscripted_rvalue (array
, idx
)
128 struct type
*elt_type
= TYPE_TARGET_TYPE (VALUE_TYPE (array
));
129 int elt_size
= TYPE_LENGTH (elt_type
);
130 int elt_offs
= elt_size
* longest_to_int (value_as_long (idx
));
133 if (elt_offs
>= TYPE_LENGTH (VALUE_TYPE (array
)))
134 error ("no such vector element");
136 v
= allocate_value (elt_type
);
137 (void) memcpy (VALUE_CONTENTS (v
), VALUE_CONTENTS (array
) + elt_offs
,
140 if (VALUE_LVAL (array
) == lval_internalvar
)
141 VALUE_LVAL (v
) = lval_internalvar_component
;
143 VALUE_LVAL (v
) = not_lval
;
144 VALUE_ADDRESS (v
) = VALUE_ADDRESS (array
);
145 VALUE_OFFSET (v
) = VALUE_OFFSET (array
) + elt_offs
;
146 VALUE_BITSIZE (v
) = elt_size
* 8;
150 /* Check to see if either argument is a structure. This is called so
151 we know whether to go ahead with the normal binop or look for a
152 user defined function instead.
154 For now, we do not overload the `=' operator. */
157 binop_user_defined_p (op
, arg1
, arg2
)
161 if (op
== BINOP_ASSIGN
)
163 return (TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_STRUCT
164 || TYPE_CODE (VALUE_TYPE (arg2
)) == TYPE_CODE_STRUCT
165 || (TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_REF
166 && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1
))) == TYPE_CODE_STRUCT
)
167 || (TYPE_CODE (VALUE_TYPE (arg2
)) == TYPE_CODE_REF
168 && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2
))) == TYPE_CODE_STRUCT
));
171 /* Check to see if argument is a structure. This is called so
172 we know whether to go ahead with the normal unop or look for a
173 user defined function instead.
175 For now, we do not overload the `&' operator. */
177 int unop_user_defined_p (op
, arg1
)
183 return (TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_STRUCT
184 || (TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_REF
185 && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1
))) == TYPE_CODE_STRUCT
));
188 /* We know either arg1 or arg2 is a structure, so try to find the right
189 user defined function. Create an argument vector that calls
190 arg1.operator @ (arg1,arg2) and return that value (where '@' is any
191 binary operator which is legal for GNU C++).
193 OP is the operatore, and if it is BINOP_ASSIGN_MODIFY, then OTHEROP
194 is the opcode saying how to modify it. Otherwise, OTHEROP is
198 value_x_binop (arg1
, arg2
, op
, otherop
)
200 enum exp_opcode op
, otherop
;
212 /* now we know that what we have to do is construct our
213 arg vector and find the right function to call it with. */
215 if (TYPE_CODE (VALUE_TYPE (arg1
)) != TYPE_CODE_STRUCT
)
216 error ("Can't do that binary op on that type"); /* FIXME be explicit */
218 argvec
= (value
*) alloca (sizeof (value
) * 4);
219 argvec
[1] = value_addr (arg1
);
223 /* make the right function name up */
224 strcpy(tstr
, "operator__");
228 case BINOP_ADD
: strcpy(ptr
,"+"); break;
229 case BINOP_SUB
: strcpy(ptr
,"-"); break;
230 case BINOP_MUL
: strcpy(ptr
,"*"); break;
231 case BINOP_DIV
: strcpy(ptr
,"/"); break;
232 case BINOP_REM
: strcpy(ptr
,"%"); break;
233 case BINOP_LSH
: strcpy(ptr
,"<<"); break;
234 case BINOP_RSH
: strcpy(ptr
,">>"); break;
235 case BINOP_LOGAND
: strcpy(ptr
,"&"); break;
236 case BINOP_LOGIOR
: strcpy(ptr
,"|"); break;
237 case BINOP_LOGXOR
: strcpy(ptr
,"^"); break;
238 case BINOP_AND
: strcpy(ptr
,"&&"); break;
239 case BINOP_OR
: strcpy(ptr
,"||"); break;
240 case BINOP_MIN
: strcpy(ptr
,"<?"); break;
241 case BINOP_MAX
: strcpy(ptr
,">?"); break;
242 case BINOP_ASSIGN
: strcpy(ptr
,"="); break;
243 case BINOP_ASSIGN_MODIFY
:
246 case BINOP_ADD
: strcpy(ptr
,"+="); break;
247 case BINOP_SUB
: strcpy(ptr
,"-="); break;
248 case BINOP_MUL
: strcpy(ptr
,"*="); break;
249 case BINOP_DIV
: strcpy(ptr
,"/="); break;
250 case BINOP_REM
: strcpy(ptr
,"%="); break;
251 case BINOP_LOGAND
: strcpy(ptr
,"&="); break;
252 case BINOP_LOGIOR
: strcpy(ptr
,"|="); break;
253 case BINOP_LOGXOR
: strcpy(ptr
,"^="); break;
255 error ("Invalid binary operation specified.");
258 case BINOP_SUBSCRIPT
: strcpy(ptr
,"[]"); break;
259 case BINOP_EQUAL
: strcpy(ptr
,"=="); break;
260 case BINOP_NOTEQUAL
: strcpy(ptr
,"!="); break;
261 case BINOP_LESS
: strcpy(ptr
,"<"); break;
262 case BINOP_GTR
: strcpy(ptr
,">"); break;
263 case BINOP_GEQ
: strcpy(ptr
,">="); break;
264 case BINOP_LEQ
: strcpy(ptr
,"<="); break;
266 error ("Invalid binary operation specified.");
268 argvec
[0] = value_struct_elt (&arg1
, argvec
+1, tstr
, &static_memfuncp
, "structure");
273 argvec
[1] = argvec
[0];
276 return call_function_by_hand (argvec
[0], 2 - static_memfuncp
, argvec
+ 1);
278 error ("member function %s not found", tstr
);
280 return call_function_by_hand (argvec
[0], 2 - static_memfuncp
, argvec
+ 1);
284 /* We know that arg1 is a structure, so try to find a unary user
285 defined operator that matches the operator in question.
286 Create an argument vector that calls arg1.operator @ (arg1)
287 and return that value (where '@' is (almost) any unary operator which
288 is legal for GNU C++). */
291 value_x_unop (arg1
, op
)
302 /* now we know that what we have to do is construct our
303 arg vector and find the right function to call it with. */
305 if (TYPE_CODE (VALUE_TYPE (arg1
)) != TYPE_CODE_STRUCT
)
306 error ("Can't do that unary op on that type"); /* FIXME be explicit */
308 argvec
= (value
*) alloca (sizeof (value
) * 3);
309 argvec
[1] = value_addr (arg1
);
312 /* make the right function name up */
313 strcpy(tstr
,"operator__");
317 case UNOP_PREINCREMENT
: strcpy(ptr
,"++"); break;
318 case UNOP_PREDECREMENT
: strcpy(ptr
,"++"); break;
319 case UNOP_POSTINCREMENT
: strcpy(ptr
,"++"); break;
320 case UNOP_POSTDECREMENT
: strcpy(ptr
,"++"); break;
321 case UNOP_ZEROP
: strcpy(ptr
,"!"); break;
322 case UNOP_LOGNOT
: strcpy(ptr
,"~"); break;
323 case UNOP_NEG
: strcpy(ptr
,"-"); break;
325 error ("Invalid binary operation specified.");
327 argvec
[0] = value_struct_elt (&arg1
, argvec
+1, tstr
, &static_memfuncp
, "structure");
332 argvec
[1] = argvec
[0];
335 return call_function_by_hand (argvec
[0], 1 - static_memfuncp
, argvec
+ 1);
337 error ("member function %s not found", tstr
);
338 return 0; /* For lint -- never reached */
341 /* Perform a binary operation on two integers or two floats.
342 Does not support addition and subtraction on pointers;
343 use value_add or value_sub if you want to handle those possibilities. */
346 value_binop (arg1
, arg2
, op
)
355 if ((TYPE_CODE (VALUE_TYPE (arg1
)) != TYPE_CODE_FLT
357 TYPE_CODE (VALUE_TYPE (arg1
)) != TYPE_CODE_INT
)
359 (TYPE_CODE (VALUE_TYPE (arg2
)) != TYPE_CODE_FLT
361 TYPE_CODE (VALUE_TYPE (arg2
)) != TYPE_CODE_INT
))
362 error ("Argument to arithmetic operation not a number.");
364 if (TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_FLT
366 TYPE_CODE (VALUE_TYPE (arg2
)) == TYPE_CODE_FLT
)
369 v1
= value_as_double (arg1
);
370 v2
= value_as_double (arg2
);
390 error ("Integer-only operation on floating point number.");
393 val
= allocate_value (builtin_type_double
);
394 SWAP_TARGET_AND_HOST (&v
, sizeof (v
));
395 *(double *) VALUE_CONTENTS_RAW (val
) = v
;
398 /* Integral operations here. */
400 /* Should we promote to unsigned longest? */
401 if ((TYPE_UNSIGNED (VALUE_TYPE (arg1
))
402 || TYPE_UNSIGNED (VALUE_TYPE (arg2
)))
403 && (TYPE_LENGTH (VALUE_TYPE (arg1
)) >= sizeof (unsigned LONGEST
)
404 || TYPE_LENGTH (VALUE_TYPE (arg1
)) >= sizeof (unsigned LONGEST
)))
406 unsigned LONGEST v1
, v2
, v
;
407 v1
= (unsigned LONGEST
) value_as_long (arg1
);
408 v2
= (unsigned LONGEST
) value_as_long (arg2
);
461 v
= v1
< v2
? v1
: v2
;
465 v
= v1
> v2
? v1
: v2
;
469 error ("Invalid binary operation on numbers.");
472 val
= allocate_value (BUILTIN_TYPE_UNSIGNED_LONGEST
);
473 SWAP_TARGET_AND_HOST (&v
, sizeof (v
));
474 *(unsigned LONGEST
*) VALUE_CONTENTS_RAW (val
) = v
;
479 v1
= value_as_long (arg1
);
480 v2
= value_as_long (arg2
);
533 v
= v1
< v2
? v1
: v2
;
537 v
= v1
> v2
? v1
: v2
;
541 error ("Invalid binary operation on numbers.");
544 val
= allocate_value (BUILTIN_TYPE_LONGEST
);
545 SWAP_TARGET_AND_HOST (&v
, sizeof (v
));
546 *(LONGEST
*) VALUE_CONTENTS_RAW (val
) = v
;
553 /* Simulate the C operator ! -- return 1 if ARG1 contains zero. */
564 if (TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_FLT
)
565 return 0 == value_as_double (arg1
);
567 len
= TYPE_LENGTH (VALUE_TYPE (arg1
));
568 p
= VALUE_CONTENTS (arg1
);
579 /* Simulate the C operator == by returning a 1
580 iff ARG1 and ARG2 have equal contents. */
583 value_equal (arg1
, arg2
)
584 register value arg1
, arg2
;
588 register char *p1
, *p2
;
589 enum type_code code1
;
590 enum type_code code2
;
595 code1
= TYPE_CODE (VALUE_TYPE (arg1
));
596 code2
= TYPE_CODE (VALUE_TYPE (arg2
));
598 if (code1
== TYPE_CODE_INT
&& code2
== TYPE_CODE_INT
)
599 return value_as_long (arg1
) == value_as_long (arg2
);
600 else if ((code1
== TYPE_CODE_FLT
|| code1
== TYPE_CODE_INT
)
601 && (code2
== TYPE_CODE_FLT
|| code2
== TYPE_CODE_INT
))
602 return value_as_double (arg1
) == value_as_double (arg2
);
604 /* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever
606 else if (code1
== TYPE_CODE_PTR
&& code2
== TYPE_CODE_INT
)
607 return value_as_pointer (arg1
) == (CORE_ADDR
) value_as_long (arg2
);
608 else if (code2
== TYPE_CODE_PTR
&& code1
== TYPE_CODE_INT
)
609 return (CORE_ADDR
) value_as_long (arg1
) == value_as_pointer (arg2
);
611 else if (code1
== code2
612 && ((len
= TYPE_LENGTH (VALUE_TYPE (arg1
)))
613 == TYPE_LENGTH (VALUE_TYPE (arg2
))))
615 p1
= VALUE_CONTENTS (arg1
);
616 p2
= VALUE_CONTENTS (arg2
);
626 error ("Invalid type combination in equality test.");
627 return 0; /* For lint -- never reached */
631 /* Simulate the C operator < by returning 1
632 iff ARG1's contents are less than ARG2's. */
635 value_less (arg1
, arg2
)
636 register value arg1
, arg2
;
638 register enum type_code code1
;
639 register enum type_code code2
;
644 code1
= TYPE_CODE (VALUE_TYPE (arg1
));
645 code2
= TYPE_CODE (VALUE_TYPE (arg2
));
647 if (code1
== TYPE_CODE_INT
&& code2
== TYPE_CODE_INT
)
649 if (TYPE_UNSIGNED (VALUE_TYPE (arg1
))
650 || TYPE_UNSIGNED (VALUE_TYPE (arg2
)))
651 return ((unsigned LONGEST
) value_as_long (arg1
)
652 < (unsigned LONGEST
) value_as_long (arg2
));
654 return value_as_long (arg1
) < value_as_long (arg2
);
656 else if ((code1
== TYPE_CODE_FLT
|| code1
== TYPE_CODE_INT
)
657 && (code2
== TYPE_CODE_FLT
|| code2
== TYPE_CODE_INT
))
658 return value_as_double (arg1
) < value_as_double (arg2
);
659 else if (code1
== TYPE_CODE_PTR
&& code2
== TYPE_CODE_PTR
)
660 return value_as_pointer (arg1
) < value_as_pointer (arg2
);
662 /* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever
664 else if (code1
== TYPE_CODE_PTR
&& code2
== TYPE_CODE_INT
)
665 return value_as_pointer (arg1
) < (CORE_ADDR
) value_as_long (arg2
);
666 else if (code2
== TYPE_CODE_PTR
&& code1
== TYPE_CODE_INT
)
667 return (CORE_ADDR
) value_as_long (arg1
) < value_as_pointer (arg2
);
671 error ("Invalid type combination in ordering comparison.");
676 /* The unary operators - and ~. Both free the argument ARG1. */
682 register struct type
*type
;
686 type
= VALUE_TYPE (arg1
);
688 if (TYPE_CODE (type
) == TYPE_CODE_FLT
)
689 return value_from_double (type
, - value_as_double (arg1
));
690 else if (TYPE_CODE (type
) == TYPE_CODE_INT
)
691 return value_from_longest (type
, - value_as_long (arg1
));
693 error ("Argument to negate operation not a number.");
694 return 0; /* For lint -- never reached */
704 if (TYPE_CODE (VALUE_TYPE (arg1
)) != TYPE_CODE_INT
)
705 error ("Argument to complement operation not an integer.");
707 return value_from_longest (VALUE_TYPE (arg1
), ~ value_as_long (arg1
));