1 /* Perform arithmetic and other operations on values, for GDB.
2 Copyright (C) 1986 Free Software Foundation, Inc.
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.
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.
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!
22 #include "initialize.h"
26 #include "expression.h"
30 value
value_x_binop ();
33 value_add (arg1
, arg2
)
36 register value val
, 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 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
);
68 return value_x_binop (arg1
, arg2
, BINOP_ADD
);
72 value_sub (arg1
, arg2
)
80 if (TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_PTR
82 TYPE_CODE (VALUE_TYPE (arg2
)) == TYPE_CODE_INT
)
84 val
= value_from_long (builtin_type_long
,
86 - TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1
))) * value_as_long (arg2
));
87 VALUE_TYPE (val
) = VALUE_TYPE (arg1
);
91 if (TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_PTR
93 VALUE_TYPE (arg1
) == VALUE_TYPE (arg2
))
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
))));
101 return value_x_binop (arg1
, arg2
, BINOP_SUB
);
104 /* Return the value of ARRAY[IDX]. */
107 value_subscript (array
, idx
)
110 return value_ind (value_add (array
, idx
));
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(). */
120 value_x_binop (arg1
, arg2
, op
)
131 if (TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_STRUCT
132 || TYPE_CODE (VALUE_TYPE (arg2
)) == TYPE_CODE_STRUCT
)
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. */
137 if (TYPE_CODE (VALUE_TYPE (arg1
)) != TYPE_CODE_STRUCT
)
138 error ("friend functions not implemented yet");
140 argvec
= (value
*) alloca (sizeof (value
) * 4);
141 argvec
[1] = value_addr (arg1
);
145 /* make the right function name up */
146 strcpy(tstr
,"operator __");
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;
165 error ("Invalid binary operation specified.");
167 argvec
[0] = value_struct_elt (arg1
, argvec
+1, tstr
, "structure");
169 return call_function (argvec
[0], 2, argvec
+ 1);
170 else error ("member function %s not found", tstr
);
173 return value_binop(arg1
, arg2
, op
);
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. */
181 value_binop (arg1
, arg2
, op
)
190 if ((TYPE_CODE (VALUE_TYPE (arg1
)) != TYPE_CODE_FLT
192 TYPE_CODE (VALUE_TYPE (arg1
)) != TYPE_CODE_INT
)
194 (TYPE_CODE (VALUE_TYPE (arg2
)) != TYPE_CODE_FLT
196 TYPE_CODE (VALUE_TYPE (arg2
)) != TYPE_CODE_INT
))
197 error ("Argument to arithmetic operation not a number.");
199 if (TYPE_CODE (VALUE_TYPE (arg1
)) == TYPE_CODE_FLT
201 TYPE_CODE (VALUE_TYPE (arg2
)) == TYPE_CODE_FLT
)
204 v1
= value_as_double (arg1
);
205 v2
= value_as_double (arg2
);
225 error ("Integer-only operation on floating point number.");
228 val
= allocate_value (builtin_type_double
);
229 *(double *) VALUE_CONTENTS (val
) = v
;
234 v1
= value_as_long (arg1
);
235 v2
= value_as_long (arg2
);
288 v
= v1
< v2
? v1
: v2
;
292 v
= v1
> v2
? v1
: v2
;
296 error ("Invalid binary operation on numbers.");
299 val
= allocate_value (builtin_type_long
);
300 *(long *) VALUE_CONTENTS (val
) = v
;
306 /* Simulate the C operator ! -- return 1 if ARG1 contains zeros. */
317 len
= TYPE_LENGTH (VALUE_TYPE (arg1
));
318 p
= VALUE_CONTENTS (arg1
);
329 /* Simulate the C operator == by returning a 1
330 iff ARG1 and ARG2 have equal contents. */
333 value_equal (arg1
, arg2
)
334 register value arg1
, arg2
;
338 register char *p1
, *p2
;
339 enum type_code code1
;
340 enum type_code code2
;
345 code1
= TYPE_CODE (VALUE_TYPE (arg1
));
346 code2
= TYPE_CODE (VALUE_TYPE (arg2
));
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
))))
360 p1
= VALUE_CONTENTS (arg1
);
361 p2
= VALUE_CONTENTS (arg2
);
370 error ("Invalid type combination in equality test.");
373 /* Simulate the C operator < by returning 1
374 iff ARG1's contents are less than ARG2's. */
377 value_less (arg1
, arg2
)
378 register value arg1
, arg2
;
380 register enum type_code code1
;
381 register enum type_code code2
;
386 code1
= TYPE_CODE (VALUE_TYPE (arg1
));
387 code2
= TYPE_CODE (VALUE_TYPE (arg2
));
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
);
398 error ("Invalid type combination in ordering comparison.");
401 /* The unary operators - and ~. Both free the argument ARG1. */
407 register struct type
*type
;
411 type
= VALUE_TYPE (arg1
);
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
));
418 error ("Argument to negate operation not a number.");
427 if (TYPE_CODE (VALUE_TYPE (arg1
)) != TYPE_CODE_INT
)
428 error ("Argument to complement operation not an integer.");
430 return value_from_long (VALUE_TYPE (arg1
), ~ value_as_long (arg1
));
This page took 0.050605 seconds and 5 git commands to generate.