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. */
25 #include "expression.h"
30 value_subscripted_rvalue
PARAMS ((value
, value
));
34 value_add (arg1
, arg2
)
37 register value valint
, valptr
;
43 if ((TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_PTR
44 || TYPE_CODE (VALUE_TYPE (arg2
)) == TYPE_CODE_PTR
)
46 (TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_INT
47 || TYPE_CODE (VALUE_TYPE (arg2
)) == TYPE_CODE_INT
))
48 /* Exactly one argument is a pointer, and one is an integer. */
50 if (TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_PTR
)
60 len
= TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (valptr
)));
61 if (len
== 0) len
= 1; /* For (void *) */
62 return value_from_longest (VALUE_TYPE (valptr
),
63 value_as_long (valptr
)
64 + (len
* value_as_long (valint
)));
67 return value_binop (arg1
, arg2
, BINOP_ADD
);
71 value_sub (arg1
, arg2
)
78 if (TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_PTR
)
80 if (TYPE_CODE (VALUE_TYPE (arg2
)) == TYPE_CODE_INT
)
82 /* pointer - integer. */
83 return value_from_longest
86 - (TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1
)))
87 * value_as_long (arg2
)));
89 else if (VALUE_TYPE (arg1
) == VALUE_TYPE (arg2
))
91 /* pointer to <type x> - pointer to <type x>. */
92 return value_from_longest
93 (builtin_type_long
, /* FIXME -- should be ptrdiff_t */
94 (value_as_long (arg1
) - value_as_long (arg2
))
95 / TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1
))));
100 First argument of `-' is a pointer and second argument is neither\n\
101 an integer nor a pointer of the same type.");
105 return value_binop (arg1
, arg2
, BINOP_SUB
);
108 /* Return the value of ARRAY[IDX]. */
111 value_subscript (array
, idx
)
114 if (TYPE_CODE (VALUE_TYPE (array
)) == TYPE_CODE_ARRAY
115 && VALUE_LVAL (array
) != lval_memory
)
116 return value_subscripted_rvalue (array
, idx
);
118 return value_ind (value_add (array
, idx
));
121 /* Return the value of EXPR[IDX], expr an aggregate rvalue
122 (eg, a vector register). This routine used to promote floats
123 to doubles, but no longer does. */
126 value_subscripted_rvalue (array
, idx
)
129 struct type
*elt_type
= TYPE_TARGET_TYPE (VALUE_TYPE (array
));
130 int elt_size
= TYPE_LENGTH (elt_type
);
131 int elt_offs
= elt_size
* longest_to_int (value_as_long (idx
));
134 if (elt_offs
>= TYPE_LENGTH (VALUE_TYPE (array
)))
135 error ("no such vector element");
137 v
= allocate_value (elt_type
);
138 bcopy (VALUE_CONTENTS (array
) + elt_offs
, VALUE_CONTENTS (v
), elt_size
);
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 zeros. */
564 len
= TYPE_LENGTH (VALUE_TYPE (arg1
));
565 p
= VALUE_CONTENTS (arg1
);
576 /* Simulate the C operator == by returning a 1
577 iff ARG1 and ARG2 have equal contents. */
580 value_equal (arg1
, arg2
)
581 register value arg1
, arg2
;
585 register char *p1
, *p2
;
586 enum type_code code1
;
587 enum type_code code2
;
592 code1
= TYPE_CODE (VALUE_TYPE (arg1
));
593 code2
= TYPE_CODE (VALUE_TYPE (arg2
));
595 if (code1
== TYPE_CODE_INT
&& code2
== TYPE_CODE_INT
)
596 return value_as_long (arg1
) == value_as_long (arg2
);
597 else if ((code1
== TYPE_CODE_FLT
|| code1
== TYPE_CODE_INT
)
598 && (code2
== TYPE_CODE_FLT
|| code2
== TYPE_CODE_INT
))
599 return value_as_double (arg1
) == value_as_double (arg2
);
601 /* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever
603 else if (code1
== TYPE_CODE_PTR
&& code2
== TYPE_CODE_INT
)
604 return value_as_pointer (arg1
) == (CORE_ADDR
) value_as_long (arg2
);
605 else if (code2
== TYPE_CODE_PTR
&& code1
== TYPE_CODE_INT
)
606 return (CORE_ADDR
) value_as_long (arg1
) == value_as_pointer (arg2
);
608 else if (code1
== code2
609 && ((len
= TYPE_LENGTH (VALUE_TYPE (arg1
)))
610 == TYPE_LENGTH (VALUE_TYPE (arg2
))))
612 p1
= VALUE_CONTENTS (arg1
);
613 p2
= VALUE_CONTENTS (arg2
);
623 error ("Invalid type combination in equality test.");
624 return 0; /* For lint -- never reached */
628 /* Simulate the C operator < by returning 1
629 iff ARG1's contents are less than ARG2's. */
632 value_less (arg1
, arg2
)
633 register value arg1
, arg2
;
635 register enum type_code code1
;
636 register enum type_code code2
;
641 code1
= TYPE_CODE (VALUE_TYPE (arg1
));
642 code2
= TYPE_CODE (VALUE_TYPE (arg2
));
644 if (code1
== TYPE_CODE_INT
&& code2
== TYPE_CODE_INT
)
646 if (TYPE_UNSIGNED (VALUE_TYPE (arg1
))
647 || TYPE_UNSIGNED (VALUE_TYPE (arg2
)))
648 return ((unsigned LONGEST
) value_as_long (arg1
)
649 < (unsigned LONGEST
) value_as_long (arg2
));
651 return value_as_long (arg1
) < value_as_long (arg2
);
653 else if ((code1
== TYPE_CODE_FLT
|| code1
== TYPE_CODE_INT
)
654 && (code2
== TYPE_CODE_FLT
|| code2
== TYPE_CODE_INT
))
655 return value_as_double (arg1
) < value_as_double (arg2
);
656 else if (code1
== TYPE_CODE_PTR
&& code2
== TYPE_CODE_PTR
)
657 return value_as_pointer (arg1
) < value_as_pointer (arg2
);
659 /* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever
661 else if (code1
== TYPE_CODE_PTR
&& code2
== TYPE_CODE_INT
)
662 return value_as_pointer (arg1
) < (CORE_ADDR
) value_as_long (arg2
);
663 else if (code2
== TYPE_CODE_PTR
&& code1
== TYPE_CODE_INT
)
664 return (CORE_ADDR
) value_as_long (arg1
) < value_as_pointer (arg2
);
668 error ("Invalid type combination in ordering comparison.");
673 /* The unary operators - and ~. Both free the argument ARG1. */
679 register struct type
*type
;
683 type
= VALUE_TYPE (arg1
);
685 if (TYPE_CODE (type
) == TYPE_CODE_FLT
)
686 return value_from_double (type
, - value_as_double (arg1
));
687 else if (TYPE_CODE (type
) == TYPE_CODE_INT
)
688 return value_from_longest (type
, - value_as_long (arg1
));
690 error ("Argument to negate operation not a number.");
691 return 0; /* For lint -- never reached */
701 if (TYPE_CODE (VALUE_TYPE (arg1
)) != TYPE_CODE_INT
)
702 error ("Argument to complement operation not an integer.");
704 return value_from_longest (VALUE_TYPE (arg1
), ~ value_as_long (arg1
));