119370Spst/* Perform arithmetic and other operations on values, for GDB. 2130803Smarcel 398944Sobrien Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 4130803Smarcel 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software 5130803Smarcel Foundation, Inc. 619370Spst 798944Sobrien This file is part of GDB. 819370Spst 998944Sobrien This program is free software; you can redistribute it and/or modify 1098944Sobrien it under the terms of the GNU General Public License as published by 1198944Sobrien the Free Software Foundation; either version 2 of the License, or 1298944Sobrien (at your option) any later version. 1319370Spst 1498944Sobrien This program is distributed in the hope that it will be useful, 1598944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1698944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1798944Sobrien GNU General Public License for more details. 1819370Spst 1998944Sobrien You should have received a copy of the GNU General Public License 2098944Sobrien along with this program; if not, write to the Free Software 2198944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2298944Sobrien Boston, MA 02111-1307, USA. */ 2319370Spst 2419370Spst#include "defs.h" 2519370Spst#include "value.h" 2619370Spst#include "symtab.h" 2719370Spst#include "gdbtypes.h" 2819370Spst#include "expression.h" 2919370Spst#include "target.h" 3019370Spst#include "language.h" 3119370Spst#include "gdb_string.h" 3298944Sobrien#include "doublest.h" 3398944Sobrien#include <math.h> 34130803Smarcel#include "infcall.h" 3519370Spst 3619370Spst/* Define whether or not the C operator '/' truncates towards zero for 3719370Spst differently signed operands (truncation direction is undefined in C). */ 3819370Spst 3919370Spst#ifndef TRUNCATION_TOWARDS_ZERO 4019370Spst#define TRUNCATION_TOWARDS_ZERO ((-5 / 2) == -2) 4119370Spst#endif 4219370Spst 4398944Sobrienstatic struct value *value_subscripted_rvalue (struct value *, struct value *, int); 4419370Spst 4598944Sobrienvoid _initialize_valarith (void); 4698944Sobrien 4746283Sdfr 48130803Smarcel/* Given a pointer, return the size of its target. 49130803Smarcel If the pointer type is void *, then return 1. 50130803Smarcel If the target type is incomplete, then error out. 51130803Smarcel This isn't a general purpose function, but just a 52130803Smarcel helper for value_sub & value_add. 53130803Smarcel*/ 54130803Smarcel 55130803Smarcelstatic LONGEST 56130803Smarcelfind_size_for_pointer_math (struct type *ptr_type) 57130803Smarcel{ 58130803Smarcel LONGEST sz = -1; 59130803Smarcel struct type *ptr_target; 60130803Smarcel 61130803Smarcel ptr_target = check_typedef (TYPE_TARGET_TYPE (ptr_type)); 62130803Smarcel 63130803Smarcel sz = TYPE_LENGTH (ptr_target); 64130803Smarcel if (sz == 0) 65130803Smarcel { 66130803Smarcel if (TYPE_CODE (ptr_type) == TYPE_CODE_VOID) 67130803Smarcel sz = 1; 68130803Smarcel else 69130803Smarcel { 70130803Smarcel char *name; 71130803Smarcel 72130803Smarcel name = TYPE_NAME (ptr_target); 73130803Smarcel if (name == NULL) 74130803Smarcel name = TYPE_TAG_NAME (ptr_target); 75130803Smarcel if (name == NULL) 76130803Smarcel error ("Cannot perform pointer math on incomplete types, " 77130803Smarcel "try casting to a known type, or void *."); 78130803Smarcel else 79130803Smarcel error ("Cannot perform pointer math on incomplete type \"%s\", " 80130803Smarcel "try casting to a known type, or void *.", name); 81130803Smarcel } 82130803Smarcel } 83130803Smarcel return sz; 84130803Smarcel} 85130803Smarcel 8698944Sobrienstruct value * 8798944Sobrienvalue_add (struct value *arg1, struct value *arg2) 8819370Spst{ 8998944Sobrien struct value *valint; 9098944Sobrien struct value *valptr; 91130803Smarcel LONGEST sz; 9219370Spst struct type *type1, *type2, *valptrtype; 9319370Spst 9419370Spst COERCE_NUMBER (arg1); 9519370Spst COERCE_NUMBER (arg2); 9619370Spst type1 = check_typedef (VALUE_TYPE (arg1)); 9719370Spst type2 = check_typedef (VALUE_TYPE (arg2)); 9819370Spst 9919370Spst if ((TYPE_CODE (type1) == TYPE_CODE_PTR 10019370Spst || TYPE_CODE (type2) == TYPE_CODE_PTR) 10119370Spst && 10219370Spst (TYPE_CODE (type1) == TYPE_CODE_INT 10319370Spst || TYPE_CODE (type2) == TYPE_CODE_INT)) 10419370Spst /* Exactly one argument is a pointer, and one is an integer. */ 10519370Spst { 10698944Sobrien struct value *retval; 10746283Sdfr 10819370Spst if (TYPE_CODE (type1) == TYPE_CODE_PTR) 10919370Spst { 11019370Spst valptr = arg1; 11119370Spst valint = arg2; 11219370Spst valptrtype = type1; 11319370Spst } 11419370Spst else 11519370Spst { 11619370Spst valptr = arg2; 11719370Spst valint = arg1; 11819370Spst valptrtype = type2; 11919370Spst } 120130803Smarcel 121130803Smarcel sz = find_size_for_pointer_math (valptrtype); 122130803Smarcel 12398944Sobrien retval = value_from_pointer (valptrtype, 12498944Sobrien value_as_address (valptr) 125130803Smarcel + (sz * value_as_long (valint))); 12646283Sdfr VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (valptr); 12746283Sdfr return retval; 12819370Spst } 12919370Spst 13019370Spst return value_binop (arg1, arg2, BINOP_ADD); 13119370Spst} 13219370Spst 13398944Sobrienstruct value * 13498944Sobrienvalue_sub (struct value *arg1, struct value *arg2) 13519370Spst{ 13619370Spst struct type *type1, *type2; 13719370Spst COERCE_NUMBER (arg1); 13819370Spst COERCE_NUMBER (arg2); 13919370Spst type1 = check_typedef (VALUE_TYPE (arg1)); 14019370Spst type2 = check_typedef (VALUE_TYPE (arg2)); 14119370Spst 14219370Spst if (TYPE_CODE (type1) == TYPE_CODE_PTR) 14319370Spst { 14419370Spst if (TYPE_CODE (type2) == TYPE_CODE_INT) 14519370Spst { 14619370Spst /* pointer - integer. */ 147130803Smarcel LONGEST sz = find_size_for_pointer_math (type1); 148130803Smarcel 14998944Sobrien return value_from_pointer (type1, 15098944Sobrien (value_as_address (arg1) 15198944Sobrien - (sz * value_as_long (arg2)))); 15219370Spst } 15319370Spst else if (TYPE_CODE (type2) == TYPE_CODE_PTR 15498944Sobrien && TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1))) 15598944Sobrien == TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type2)))) 15619370Spst { 15719370Spst /* pointer to <type x> - pointer to <type x>. */ 15819370Spst LONGEST sz = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1))); 15919370Spst return value_from_longest 16098944Sobrien (builtin_type_long, /* FIXME -- should be ptrdiff_t */ 16119370Spst (value_as_long (arg1) - value_as_long (arg2)) / sz); 16219370Spst } 16319370Spst else 16419370Spst { 16519370Spst error ("\ 16619370SpstFirst argument of `-' is a pointer and second argument is neither\n\ 16719370Spstan integer nor a pointer of the same type."); 16819370Spst } 16919370Spst } 17019370Spst 17119370Spst return value_binop (arg1, arg2, BINOP_SUB); 17219370Spst} 17319370Spst 17419370Spst/* Return the value of ARRAY[IDX]. 17519370Spst See comments in value_coerce_array() for rationale for reason for 17619370Spst doing lower bounds adjustment here rather than there. 17719370Spst FIXME: Perhaps we should validate that the index is valid and if 17819370Spst verbosity is set, warn about invalid indices (but still use them). */ 17919370Spst 18098944Sobrienstruct value * 18198944Sobrienvalue_subscript (struct value *array, struct value *idx) 18219370Spst{ 18398944Sobrien struct value *bound; 18419370Spst int c_style = current_language->c_style_arrays; 18519370Spst struct type *tarray; 18619370Spst 18719370Spst COERCE_REF (array); 18819370Spst tarray = check_typedef (VALUE_TYPE (array)); 18919370Spst COERCE_VARYING_ARRAY (array, tarray); 19019370Spst 19119370Spst if (TYPE_CODE (tarray) == TYPE_CODE_ARRAY 19219370Spst || TYPE_CODE (tarray) == TYPE_CODE_STRING) 19319370Spst { 19419370Spst struct type *range_type = TYPE_INDEX_TYPE (tarray); 19519370Spst LONGEST lowerbound, upperbound; 19619370Spst get_discrete_bounds (range_type, &lowerbound, &upperbound); 19719370Spst 19819370Spst if (VALUE_LVAL (array) != lval_memory) 19919370Spst return value_subscripted_rvalue (array, idx, lowerbound); 20019370Spst 20119370Spst if (c_style == 0) 20219370Spst { 20319370Spst LONGEST index = value_as_long (idx); 20419370Spst if (index >= lowerbound && index <= upperbound) 20519370Spst return value_subscripted_rvalue (array, idx, lowerbound); 20619370Spst warning ("array or string index out of range"); 20719370Spst /* fall doing C stuff */ 20819370Spst c_style = 1; 20919370Spst } 21019370Spst 21119370Spst if (lowerbound != 0) 21219370Spst { 21319370Spst bound = value_from_longest (builtin_type_int, (LONGEST) lowerbound); 21419370Spst idx = value_sub (idx, bound); 21519370Spst } 21619370Spst 21719370Spst array = value_coerce_array (array); 21819370Spst } 21919370Spst 22019370Spst if (TYPE_CODE (tarray) == TYPE_CODE_BITSTRING) 22119370Spst { 22219370Spst struct type *range_type = TYPE_INDEX_TYPE (tarray); 22319370Spst LONGEST index = value_as_long (idx); 22498944Sobrien struct value *v; 22519370Spst int offset, byte, bit_index; 22619370Spst LONGEST lowerbound, upperbound; 22719370Spst get_discrete_bounds (range_type, &lowerbound, &upperbound); 22819370Spst if (index < lowerbound || index > upperbound) 22919370Spst error ("bitstring index out of range"); 23019370Spst index -= lowerbound; 23119370Spst offset = index / TARGET_CHAR_BIT; 23298944Sobrien byte = *((char *) VALUE_CONTENTS (array) + offset); 23319370Spst bit_index = index % TARGET_CHAR_BIT; 23419370Spst byte >>= (BITS_BIG_ENDIAN ? TARGET_CHAR_BIT - 1 - bit_index : bit_index); 23519370Spst v = value_from_longest (LA_BOOL_TYPE, byte & 1); 23619370Spst VALUE_BITPOS (v) = bit_index; 23719370Spst VALUE_BITSIZE (v) = 1; 23819370Spst VALUE_LVAL (v) = VALUE_LVAL (array); 23919370Spst if (VALUE_LVAL (array) == lval_internalvar) 24019370Spst VALUE_LVAL (v) = lval_internalvar_component; 24119370Spst VALUE_ADDRESS (v) = VALUE_ADDRESS (array); 24219370Spst VALUE_OFFSET (v) = offset + VALUE_OFFSET (array); 24319370Spst return v; 24419370Spst } 24519370Spst 24619370Spst if (c_style) 24719370Spst return value_ind (value_add (array, idx)); 24819370Spst else 24919370Spst error ("not an array or string"); 25019370Spst} 25119370Spst 25219370Spst/* Return the value of EXPR[IDX], expr an aggregate rvalue 25319370Spst (eg, a vector register). This routine used to promote floats 25419370Spst to doubles, but no longer does. */ 25519370Spst 25698944Sobrienstatic struct value * 25798944Sobrienvalue_subscripted_rvalue (struct value *array, struct value *idx, int lowerbound) 25819370Spst{ 25919370Spst struct type *array_type = check_typedef (VALUE_TYPE (array)); 26019370Spst struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type)); 26119370Spst unsigned int elt_size = TYPE_LENGTH (elt_type); 26219370Spst LONGEST index = value_as_long (idx); 26319370Spst unsigned int elt_offs = elt_size * longest_to_int (index - lowerbound); 26498944Sobrien struct value *v; 26519370Spst 26619370Spst if (index < lowerbound || elt_offs >= TYPE_LENGTH (array_type)) 26719370Spst error ("no such vector element"); 26819370Spst 26919370Spst v = allocate_value (elt_type); 27019370Spst if (VALUE_LAZY (array)) 27119370Spst VALUE_LAZY (v) = 1; 27219370Spst else 27319370Spst memcpy (VALUE_CONTENTS (v), VALUE_CONTENTS (array) + elt_offs, elt_size); 27419370Spst 27519370Spst if (VALUE_LVAL (array) == lval_internalvar) 27619370Spst VALUE_LVAL (v) = lval_internalvar_component; 27719370Spst else 27819370Spst VALUE_LVAL (v) = VALUE_LVAL (array); 27919370Spst VALUE_ADDRESS (v) = VALUE_ADDRESS (array); 280130803Smarcel VALUE_REGNO (v) = VALUE_REGNO (array); 28119370Spst VALUE_OFFSET (v) = VALUE_OFFSET (array) + elt_offs; 28219370Spst return v; 28319370Spst} 28419370Spst 28519370Spst/* Check to see if either argument is a structure. This is called so 28619370Spst we know whether to go ahead with the normal binop or look for a 28719370Spst user defined function instead. 28819370Spst 28919370Spst For now, we do not overload the `=' operator. */ 29019370Spst 29119370Spstint 29298944Sobrienbinop_user_defined_p (enum exp_opcode op, struct value *arg1, struct value *arg2) 29319370Spst{ 29419370Spst struct type *type1, *type2; 29519370Spst if (op == BINOP_ASSIGN || op == BINOP_CONCAT) 29619370Spst return 0; 29719370Spst type1 = check_typedef (VALUE_TYPE (arg1)); 29819370Spst type2 = check_typedef (VALUE_TYPE (arg2)); 29919370Spst return (TYPE_CODE (type1) == TYPE_CODE_STRUCT 30019370Spst || TYPE_CODE (type2) == TYPE_CODE_STRUCT 30119370Spst || (TYPE_CODE (type1) == TYPE_CODE_REF 30219370Spst && TYPE_CODE (TYPE_TARGET_TYPE (type1)) == TYPE_CODE_STRUCT) 30319370Spst || (TYPE_CODE (type2) == TYPE_CODE_REF 30419370Spst && TYPE_CODE (TYPE_TARGET_TYPE (type2)) == TYPE_CODE_STRUCT)); 30519370Spst} 30619370Spst 30719370Spst/* Check to see if argument is a structure. This is called so 30819370Spst we know whether to go ahead with the normal unop or look for a 30919370Spst user defined function instead. 31019370Spst 31119370Spst For now, we do not overload the `&' operator. */ 31219370Spst 31398944Sobrienint 31498944Sobrienunop_user_defined_p (enum exp_opcode op, struct value *arg1) 31519370Spst{ 31619370Spst struct type *type1; 31719370Spst if (op == UNOP_ADDR) 31819370Spst return 0; 31919370Spst type1 = check_typedef (VALUE_TYPE (arg1)); 32019370Spst for (;;) 32119370Spst { 32219370Spst if (TYPE_CODE (type1) == TYPE_CODE_STRUCT) 32319370Spst return 1; 32419370Spst else if (TYPE_CODE (type1) == TYPE_CODE_REF) 32519370Spst type1 = TYPE_TARGET_TYPE (type1); 32619370Spst else 32719370Spst return 0; 32819370Spst } 32919370Spst} 33019370Spst 33119370Spst/* We know either arg1 or arg2 is a structure, so try to find the right 33219370Spst user defined function. Create an argument vector that calls 33319370Spst arg1.operator @ (arg1,arg2) and return that value (where '@' is any 33419370Spst binary operator which is legal for GNU C++). 33519370Spst 33619370Spst OP is the operatore, and if it is BINOP_ASSIGN_MODIFY, then OTHEROP 33719370Spst is the opcode saying how to modify it. Otherwise, OTHEROP is 33819370Spst unused. */ 33919370Spst 34098944Sobrienstruct value * 34198944Sobrienvalue_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op, 34298944Sobrien enum exp_opcode otherop, enum noside noside) 34319370Spst{ 34498944Sobrien struct value **argvec; 34519370Spst char *ptr; 34619370Spst char tstr[13]; 34719370Spst int static_memfuncp; 34819370Spst 34919370Spst COERCE_REF (arg1); 35019370Spst COERCE_REF (arg2); 35119370Spst COERCE_ENUM (arg1); 35219370Spst COERCE_ENUM (arg2); 35319370Spst 35419370Spst /* now we know that what we have to do is construct our 35519370Spst arg vector and find the right function to call it with. */ 35619370Spst 35719370Spst if (TYPE_CODE (check_typedef (VALUE_TYPE (arg1))) != TYPE_CODE_STRUCT) 35898944Sobrien error ("Can't do that binary op on that type"); /* FIXME be explicit */ 35919370Spst 36098944Sobrien argvec = (struct value **) alloca (sizeof (struct value *) * 4); 36119370Spst argvec[1] = value_addr (arg1); 36219370Spst argvec[2] = arg2; 36319370Spst argvec[3] = 0; 36419370Spst 36598944Sobrien /* make the right function name up */ 36698944Sobrien strcpy (tstr, "operator__"); 36798944Sobrien ptr = tstr + 8; 36819370Spst switch (op) 36919370Spst { 37098944Sobrien case BINOP_ADD: 37198944Sobrien strcpy (ptr, "+"); 37298944Sobrien break; 37398944Sobrien case BINOP_SUB: 37498944Sobrien strcpy (ptr, "-"); 37598944Sobrien break; 37698944Sobrien case BINOP_MUL: 37798944Sobrien strcpy (ptr, "*"); 37898944Sobrien break; 37998944Sobrien case BINOP_DIV: 38098944Sobrien strcpy (ptr, "/"); 38198944Sobrien break; 38298944Sobrien case BINOP_REM: 38398944Sobrien strcpy (ptr, "%"); 38498944Sobrien break; 38598944Sobrien case BINOP_LSH: 38698944Sobrien strcpy (ptr, "<<"); 38798944Sobrien break; 38898944Sobrien case BINOP_RSH: 38998944Sobrien strcpy (ptr, ">>"); 39098944Sobrien break; 39198944Sobrien case BINOP_BITWISE_AND: 39298944Sobrien strcpy (ptr, "&"); 39398944Sobrien break; 39498944Sobrien case BINOP_BITWISE_IOR: 39598944Sobrien strcpy (ptr, "|"); 39698944Sobrien break; 39798944Sobrien case BINOP_BITWISE_XOR: 39898944Sobrien strcpy (ptr, "^"); 39998944Sobrien break; 40098944Sobrien case BINOP_LOGICAL_AND: 40198944Sobrien strcpy (ptr, "&&"); 40298944Sobrien break; 40398944Sobrien case BINOP_LOGICAL_OR: 40498944Sobrien strcpy (ptr, "||"); 40598944Sobrien break; 40698944Sobrien case BINOP_MIN: 40798944Sobrien strcpy (ptr, "<?"); 40898944Sobrien break; 40998944Sobrien case BINOP_MAX: 41098944Sobrien strcpy (ptr, ">?"); 41198944Sobrien break; 41298944Sobrien case BINOP_ASSIGN: 41398944Sobrien strcpy (ptr, "="); 41498944Sobrien break; 41598944Sobrien case BINOP_ASSIGN_MODIFY: 41619370Spst switch (otherop) 41719370Spst { 41898944Sobrien case BINOP_ADD: 41998944Sobrien strcpy (ptr, "+="); 42098944Sobrien break; 42198944Sobrien case BINOP_SUB: 42298944Sobrien strcpy (ptr, "-="); 42398944Sobrien break; 42498944Sobrien case BINOP_MUL: 42598944Sobrien strcpy (ptr, "*="); 42698944Sobrien break; 42798944Sobrien case BINOP_DIV: 42898944Sobrien strcpy (ptr, "/="); 42998944Sobrien break; 43098944Sobrien case BINOP_REM: 43198944Sobrien strcpy (ptr, "%="); 43298944Sobrien break; 43398944Sobrien case BINOP_BITWISE_AND: 43498944Sobrien strcpy (ptr, "&="); 43598944Sobrien break; 43698944Sobrien case BINOP_BITWISE_IOR: 43798944Sobrien strcpy (ptr, "|="); 43898944Sobrien break; 43998944Sobrien case BINOP_BITWISE_XOR: 44098944Sobrien strcpy (ptr, "^="); 44198944Sobrien break; 44298944Sobrien case BINOP_MOD: /* invalid */ 44319370Spst default: 44419370Spst error ("Invalid binary operation specified."); 44519370Spst } 44619370Spst break; 44798944Sobrien case BINOP_SUBSCRIPT: 44898944Sobrien strcpy (ptr, "[]"); 44998944Sobrien break; 45098944Sobrien case BINOP_EQUAL: 45198944Sobrien strcpy (ptr, "=="); 45298944Sobrien break; 45398944Sobrien case BINOP_NOTEQUAL: 45498944Sobrien strcpy (ptr, "!="); 45598944Sobrien break; 45698944Sobrien case BINOP_LESS: 45798944Sobrien strcpy (ptr, "<"); 45898944Sobrien break; 45998944Sobrien case BINOP_GTR: 46098944Sobrien strcpy (ptr, ">"); 46198944Sobrien break; 46298944Sobrien case BINOP_GEQ: 46398944Sobrien strcpy (ptr, ">="); 46498944Sobrien break; 46598944Sobrien case BINOP_LEQ: 46698944Sobrien strcpy (ptr, "<="); 46798944Sobrien break; 46898944Sobrien case BINOP_MOD: /* invalid */ 46919370Spst default: 47019370Spst error ("Invalid binary operation specified."); 47119370Spst } 47219370Spst 47398944Sobrien argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure"); 47498944Sobrien 47519370Spst if (argvec[0]) 47619370Spst { 47719370Spst if (static_memfuncp) 47819370Spst { 47919370Spst argvec[1] = argvec[0]; 48019370Spst argvec++; 48119370Spst } 48246283Sdfr if (noside == EVAL_AVOID_SIDE_EFFECTS) 48346283Sdfr { 48446283Sdfr struct type *return_type; 48546283Sdfr return_type 48646283Sdfr = TYPE_TARGET_TYPE (check_typedef (VALUE_TYPE (argvec[0]))); 48746283Sdfr return value_zero (return_type, VALUE_LVAL (arg1)); 48846283Sdfr } 48919370Spst return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1); 49019370Spst } 49119370Spst error ("member function %s not found", tstr); 49219370Spst#ifdef lint 49319370Spst return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1); 49419370Spst#endif 49519370Spst} 49619370Spst 49719370Spst/* We know that arg1 is a structure, so try to find a unary user 49819370Spst defined operator that matches the operator in question. 49919370Spst Create an argument vector that calls arg1.operator @ (arg1) 50019370Spst and return that value (where '@' is (almost) any unary operator which 50119370Spst is legal for GNU C++). */ 50219370Spst 50398944Sobrienstruct value * 50498944Sobrienvalue_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside) 50519370Spst{ 50698944Sobrien struct value **argvec; 50719370Spst char *ptr, *mangle_ptr; 50819370Spst char tstr[13], mangle_tstr[13]; 50998944Sobrien int static_memfuncp, nargs; 51019370Spst 51119370Spst COERCE_REF (arg1); 51219370Spst COERCE_ENUM (arg1); 51319370Spst 51419370Spst /* now we know that what we have to do is construct our 51519370Spst arg vector and find the right function to call it with. */ 51619370Spst 51719370Spst if (TYPE_CODE (check_typedef (VALUE_TYPE (arg1))) != TYPE_CODE_STRUCT) 51898944Sobrien error ("Can't do that unary op on that type"); /* FIXME be explicit */ 51919370Spst 52098944Sobrien argvec = (struct value **) alloca (sizeof (struct value *) * 4); 52119370Spst argvec[1] = value_addr (arg1); 52219370Spst argvec[2] = 0; 52319370Spst 52498944Sobrien nargs = 1; 52598944Sobrien 52698944Sobrien /* make the right function name up */ 52798944Sobrien strcpy (tstr, "operator__"); 52898944Sobrien ptr = tstr + 8; 52998944Sobrien strcpy (mangle_tstr, "__"); 53098944Sobrien mangle_ptr = mangle_tstr + 2; 53119370Spst switch (op) 53219370Spst { 53398944Sobrien case UNOP_PREINCREMENT: 53498944Sobrien strcpy (ptr, "++"); 53598944Sobrien break; 53698944Sobrien case UNOP_PREDECREMENT: 53798944Sobrien strcpy (ptr, "--"); 53898944Sobrien break; 53998944Sobrien case UNOP_POSTINCREMENT: 54098944Sobrien strcpy (ptr, "++"); 54198944Sobrien argvec[2] = value_from_longest (builtin_type_int, 0); 54298944Sobrien argvec[3] = 0; 54398944Sobrien nargs ++; 54498944Sobrien break; 54598944Sobrien case UNOP_POSTDECREMENT: 54698944Sobrien strcpy (ptr, "--"); 54798944Sobrien argvec[2] = value_from_longest (builtin_type_int, 0); 54898944Sobrien argvec[3] = 0; 54998944Sobrien nargs ++; 55098944Sobrien break; 55198944Sobrien case UNOP_LOGICAL_NOT: 55298944Sobrien strcpy (ptr, "!"); 55398944Sobrien break; 55498944Sobrien case UNOP_COMPLEMENT: 55598944Sobrien strcpy (ptr, "~"); 55698944Sobrien break; 55798944Sobrien case UNOP_NEG: 55898944Sobrien strcpy (ptr, "-"); 55998944Sobrien break; 56098944Sobrien case UNOP_IND: 56198944Sobrien strcpy (ptr, "*"); 56298944Sobrien break; 56319370Spst default: 56446283Sdfr error ("Invalid unary operation specified."); 56519370Spst } 56619370Spst 56798944Sobrien argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure"); 56819370Spst 56919370Spst if (argvec[0]) 57019370Spst { 57119370Spst if (static_memfuncp) 57219370Spst { 57319370Spst argvec[1] = argvec[0]; 57498944Sobrien nargs --; 57519370Spst argvec++; 57619370Spst } 57746283Sdfr if (noside == EVAL_AVOID_SIDE_EFFECTS) 57846283Sdfr { 57946283Sdfr struct type *return_type; 58046283Sdfr return_type 58146283Sdfr = TYPE_TARGET_TYPE (check_typedef (VALUE_TYPE (argvec[0]))); 58246283Sdfr return value_zero (return_type, VALUE_LVAL (arg1)); 58346283Sdfr } 58498944Sobrien return call_function_by_hand (argvec[0], nargs, argvec + 1); 58519370Spst } 58619370Spst error ("member function %s not found", tstr); 58798944Sobrien return 0; /* For lint -- never reached */ 58819370Spst} 58998944Sobrien 59019370Spst 59119370Spst/* Concatenate two values with the following conditions: 59219370Spst 59398944Sobrien (1) Both values must be either bitstring values or character string 59498944Sobrien values and the resulting value consists of the concatenation of 59598944Sobrien ARG1 followed by ARG2. 59619370Spst 59798944Sobrien or 59819370Spst 59998944Sobrien One value must be an integer value and the other value must be 60098944Sobrien either a bitstring value or character string value, which is 60198944Sobrien to be repeated by the number of times specified by the integer 60298944Sobrien value. 60319370Spst 60419370Spst 60598944Sobrien (2) Boolean values are also allowed and are treated as bit string 60698944Sobrien values of length 1. 60719370Spst 60898944Sobrien (3) Character values are also allowed and are treated as character 60998944Sobrien string values of length 1. 61098944Sobrien */ 61119370Spst 61298944Sobrienstruct value * 61398944Sobrienvalue_concat (struct value *arg1, struct value *arg2) 61419370Spst{ 61598944Sobrien struct value *inval1; 61698944Sobrien struct value *inval2; 61798944Sobrien struct value *outval = NULL; 61819370Spst int inval1len, inval2len; 61919370Spst int count, idx; 62019370Spst char *ptr; 62119370Spst char inchar; 62219370Spst struct type *type1 = check_typedef (VALUE_TYPE (arg1)); 62319370Spst struct type *type2 = check_typedef (VALUE_TYPE (arg2)); 62419370Spst 62519370Spst COERCE_VARYING_ARRAY (arg1, type1); 62619370Spst COERCE_VARYING_ARRAY (arg2, type2); 62719370Spst 62819370Spst /* First figure out if we are dealing with two values to be concatenated 62919370Spst or a repeat count and a value to be repeated. INVAL1 is set to the 63019370Spst first of two concatenated values, or the repeat count. INVAL2 is set 63119370Spst to the second of the two concatenated values or the value to be 63219370Spst repeated. */ 63319370Spst 63419370Spst if (TYPE_CODE (type2) == TYPE_CODE_INT) 63519370Spst { 63619370Spst struct type *tmp = type1; 63719370Spst type1 = tmp; 63819370Spst tmp = type2; 63919370Spst inval1 = arg2; 64019370Spst inval2 = arg1; 64119370Spst } 64219370Spst else 64319370Spst { 64419370Spst inval1 = arg1; 64519370Spst inval2 = arg2; 64619370Spst } 64719370Spst 64819370Spst /* Now process the input values. */ 64919370Spst 65019370Spst if (TYPE_CODE (type1) == TYPE_CODE_INT) 65119370Spst { 65219370Spst /* We have a repeat count. Validate the second value and then 65398944Sobrien construct a value repeated that many times. */ 65419370Spst if (TYPE_CODE (type2) == TYPE_CODE_STRING 65519370Spst || TYPE_CODE (type2) == TYPE_CODE_CHAR) 65619370Spst { 65719370Spst count = longest_to_int (value_as_long (inval1)); 65819370Spst inval2len = TYPE_LENGTH (type2); 65919370Spst ptr = (char *) alloca (count * inval2len); 66019370Spst if (TYPE_CODE (type2) == TYPE_CODE_CHAR) 66119370Spst { 66219370Spst inchar = (char) unpack_long (type2, 66319370Spst VALUE_CONTENTS (inval2)); 66419370Spst for (idx = 0; idx < count; idx++) 66519370Spst { 66619370Spst *(ptr + idx) = inchar; 66719370Spst } 66819370Spst } 66919370Spst else 67019370Spst { 67119370Spst for (idx = 0; idx < count; idx++) 67219370Spst { 67319370Spst memcpy (ptr + (idx * inval2len), VALUE_CONTENTS (inval2), 67419370Spst inval2len); 67519370Spst } 67619370Spst } 67719370Spst outval = value_string (ptr, count * inval2len); 67819370Spst } 67919370Spst else if (TYPE_CODE (type2) == TYPE_CODE_BITSTRING 68019370Spst || TYPE_CODE (type2) == TYPE_CODE_BOOL) 68119370Spst { 68219370Spst error ("unimplemented support for bitstring/boolean repeats"); 68319370Spst } 68419370Spst else 68519370Spst { 68619370Spst error ("can't repeat values of that type"); 68719370Spst } 68819370Spst } 68919370Spst else if (TYPE_CODE (type1) == TYPE_CODE_STRING 69098944Sobrien || TYPE_CODE (type1) == TYPE_CODE_CHAR) 69119370Spst { 69219370Spst /* We have two character strings to concatenate. */ 69319370Spst if (TYPE_CODE (type2) != TYPE_CODE_STRING 69419370Spst && TYPE_CODE (type2) != TYPE_CODE_CHAR) 69519370Spst { 69619370Spst error ("Strings can only be concatenated with other strings."); 69719370Spst } 69819370Spst inval1len = TYPE_LENGTH (type1); 69919370Spst inval2len = TYPE_LENGTH (type2); 70019370Spst ptr = (char *) alloca (inval1len + inval2len); 70119370Spst if (TYPE_CODE (type1) == TYPE_CODE_CHAR) 70219370Spst { 70319370Spst *ptr = (char) unpack_long (type1, VALUE_CONTENTS (inval1)); 70419370Spst } 70519370Spst else 70619370Spst { 70719370Spst memcpy (ptr, VALUE_CONTENTS (inval1), inval1len); 70819370Spst } 70919370Spst if (TYPE_CODE (type2) == TYPE_CODE_CHAR) 71019370Spst { 71198944Sobrien *(ptr + inval1len) = 71219370Spst (char) unpack_long (type2, VALUE_CONTENTS (inval2)); 71319370Spst } 71419370Spst else 71519370Spst { 71619370Spst memcpy (ptr + inval1len, VALUE_CONTENTS (inval2), inval2len); 71719370Spst } 71819370Spst outval = value_string (ptr, inval1len + inval2len); 71919370Spst } 72019370Spst else if (TYPE_CODE (type1) == TYPE_CODE_BITSTRING 72119370Spst || TYPE_CODE (type1) == TYPE_CODE_BOOL) 72219370Spst { 72319370Spst /* We have two bitstrings to concatenate. */ 72419370Spst if (TYPE_CODE (type2) != TYPE_CODE_BITSTRING 72519370Spst && TYPE_CODE (type2) != TYPE_CODE_BOOL) 72619370Spst { 72719370Spst error ("Bitstrings or booleans can only be concatenated with other bitstrings or booleans."); 72819370Spst } 72919370Spst error ("unimplemented support for bitstring/boolean concatenation."); 73098944Sobrien } 73119370Spst else 73219370Spst { 73319370Spst /* We don't know how to concatenate these operands. */ 73419370Spst error ("illegal operands for concatenation."); 73519370Spst } 73619370Spst return (outval); 73719370Spst} 73819370Spst 73919370Spst 74098944Sobrien 74119370Spst/* Perform a binary operation on two operands which have reasonable 74219370Spst representations as integers or floats. This includes booleans, 74319370Spst characters, integers, or floats. 74419370Spst Does not support addition and subtraction on pointers; 74519370Spst use value_add or value_sub if you want to handle those possibilities. */ 74619370Spst 74798944Sobrienstruct value * 74898944Sobrienvalue_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) 74919370Spst{ 75098944Sobrien struct value *val; 75119370Spst struct type *type1, *type2; 75219370Spst 75319370Spst COERCE_REF (arg1); 75419370Spst COERCE_REF (arg2); 75519370Spst COERCE_ENUM (arg1); 75619370Spst COERCE_ENUM (arg2); 75719370Spst type1 = check_typedef (VALUE_TYPE (arg1)); 75819370Spst type2 = check_typedef (VALUE_TYPE (arg2)); 75919370Spst 76019370Spst if ((TYPE_CODE (type1) != TYPE_CODE_FLT 76119370Spst && TYPE_CODE (type1) != TYPE_CODE_CHAR 76219370Spst && TYPE_CODE (type1) != TYPE_CODE_INT 76319370Spst && TYPE_CODE (type1) != TYPE_CODE_BOOL 76419370Spst && TYPE_CODE (type1) != TYPE_CODE_RANGE) 76519370Spst || 76619370Spst (TYPE_CODE (type2) != TYPE_CODE_FLT 76719370Spst && TYPE_CODE (type2) != TYPE_CODE_CHAR 76819370Spst && TYPE_CODE (type2) != TYPE_CODE_INT 76919370Spst && TYPE_CODE (type2) != TYPE_CODE_BOOL 77019370Spst && TYPE_CODE (type2) != TYPE_CODE_RANGE)) 77119370Spst error ("Argument to arithmetic operation not a number or boolean."); 77219370Spst 77319370Spst if (TYPE_CODE (type1) == TYPE_CODE_FLT 77419370Spst || 77519370Spst TYPE_CODE (type2) == TYPE_CODE_FLT) 77619370Spst { 77719370Spst /* FIXME-if-picky-about-floating-accuracy: Should be doing this 77898944Sobrien in target format. real.c in GCC probably has the necessary 77998944Sobrien code. */ 78098944Sobrien DOUBLEST v1, v2, v = 0; 78119370Spst v1 = value_as_double (arg1); 78219370Spst v2 = value_as_double (arg2); 78319370Spst switch (op) 78419370Spst { 78519370Spst case BINOP_ADD: 78619370Spst v = v1 + v2; 78719370Spst break; 78819370Spst 78919370Spst case BINOP_SUB: 79019370Spst v = v1 - v2; 79119370Spst break; 79219370Spst 79319370Spst case BINOP_MUL: 79419370Spst v = v1 * v2; 79519370Spst break; 79619370Spst 79719370Spst case BINOP_DIV: 79819370Spst v = v1 / v2; 79919370Spst break; 80019370Spst 80198944Sobrien case BINOP_EXP: 80298944Sobrien v = pow (v1, v2); 80398944Sobrien if (errno) 804130803Smarcel error ("Cannot perform exponentiation: %s", safe_strerror (errno)); 80598944Sobrien break; 80698944Sobrien 80719370Spst default: 80819370Spst error ("Integer-only operation on floating point number."); 80919370Spst } 81019370Spst 81119370Spst /* If either arg was long double, make sure that value is also long 81298944Sobrien double. */ 81319370Spst 81498944Sobrien if (TYPE_LENGTH (type1) * 8 > TARGET_DOUBLE_BIT 81598944Sobrien || TYPE_LENGTH (type2) * 8 > TARGET_DOUBLE_BIT) 81619370Spst val = allocate_value (builtin_type_long_double); 81719370Spst else 81819370Spst val = allocate_value (builtin_type_double); 81919370Spst 82098944Sobrien store_typed_floating (VALUE_CONTENTS_RAW (val), VALUE_TYPE (val), v); 82119370Spst } 82219370Spst else if (TYPE_CODE (type1) == TYPE_CODE_BOOL 82319370Spst && 82419370Spst TYPE_CODE (type2) == TYPE_CODE_BOOL) 82598944Sobrien { 82698944Sobrien LONGEST v1, v2, v = 0; 82798944Sobrien v1 = value_as_long (arg1); 82898944Sobrien v2 = value_as_long (arg2); 82998944Sobrien 83098944Sobrien switch (op) 83198944Sobrien { 83298944Sobrien case BINOP_BITWISE_AND: 83398944Sobrien v = v1 & v2; 83498944Sobrien break; 83598944Sobrien 83698944Sobrien case BINOP_BITWISE_IOR: 83798944Sobrien v = v1 | v2; 83898944Sobrien break; 83998944Sobrien 84098944Sobrien case BINOP_BITWISE_XOR: 84198944Sobrien v = v1 ^ v2; 84298944Sobrien break; 84398944Sobrien 84498944Sobrien case BINOP_EQUAL: 84598944Sobrien v = v1 == v2; 84698944Sobrien break; 84798944Sobrien 84898944Sobrien case BINOP_NOTEQUAL: 84998944Sobrien v = v1 != v2; 85098944Sobrien break; 85198944Sobrien 85298944Sobrien default: 85398944Sobrien error ("Invalid operation on booleans."); 85498944Sobrien } 85598944Sobrien 85698944Sobrien val = allocate_value (type1); 85798944Sobrien store_signed_integer (VALUE_CONTENTS_RAW (val), 85898944Sobrien TYPE_LENGTH (type1), 85998944Sobrien v); 86098944Sobrien } 86119370Spst else 86219370Spst /* Integral operations here. */ 86319370Spst /* FIXME: Also mixed integral/booleans, with result an integer. */ 86419370Spst /* FIXME: This implements ANSI C rules (also correct for C++). 865130803Smarcel What about FORTRAN and (the deleted) chill ? */ 86619370Spst { 86719370Spst unsigned int promoted_len1 = TYPE_LENGTH (type1); 86819370Spst unsigned int promoted_len2 = TYPE_LENGTH (type2); 86919370Spst int is_unsigned1 = TYPE_UNSIGNED (type1); 87019370Spst int is_unsigned2 = TYPE_UNSIGNED (type2); 87119370Spst unsigned int result_len; 87219370Spst int unsigned_operation; 87319370Spst 87419370Spst /* Determine type length and signedness after promotion for 87598944Sobrien both operands. */ 87619370Spst if (promoted_len1 < TYPE_LENGTH (builtin_type_int)) 87719370Spst { 87819370Spst is_unsigned1 = 0; 87919370Spst promoted_len1 = TYPE_LENGTH (builtin_type_int); 88019370Spst } 88119370Spst if (promoted_len2 < TYPE_LENGTH (builtin_type_int)) 88219370Spst { 88319370Spst is_unsigned2 = 0; 88419370Spst promoted_len2 = TYPE_LENGTH (builtin_type_int); 88519370Spst } 88619370Spst 88719370Spst /* Determine type length of the result, and if the operation should 88898944Sobrien be done unsigned. 88998944Sobrien Use the signedness of the operand with the greater length. 89098944Sobrien If both operands are of equal length, use unsigned operation 89198944Sobrien if one of the operands is unsigned. */ 89219370Spst if (promoted_len1 > promoted_len2) 89319370Spst { 89419370Spst unsigned_operation = is_unsigned1; 89519370Spst result_len = promoted_len1; 89619370Spst } 89719370Spst else if (promoted_len2 > promoted_len1) 89819370Spst { 89919370Spst unsigned_operation = is_unsigned2; 90019370Spst result_len = promoted_len2; 90119370Spst } 90219370Spst else 90319370Spst { 90419370Spst unsigned_operation = is_unsigned1 || is_unsigned2; 90519370Spst result_len = promoted_len1; 90619370Spst } 90719370Spst 90819370Spst if (unsigned_operation) 90919370Spst { 91098944Sobrien ULONGEST v1, v2, v = 0; 91146283Sdfr v1 = (ULONGEST) value_as_long (arg1); 91246283Sdfr v2 = (ULONGEST) value_as_long (arg2); 91319370Spst 91419370Spst /* Truncate values to the type length of the result. */ 91546283Sdfr if (result_len < sizeof (ULONGEST)) 91619370Spst { 91719370Spst v1 &= ((LONGEST) 1 << HOST_CHAR_BIT * result_len) - 1; 91819370Spst v2 &= ((LONGEST) 1 << HOST_CHAR_BIT * result_len) - 1; 91919370Spst } 92098944Sobrien 92119370Spst switch (op) 92219370Spst { 92319370Spst case BINOP_ADD: 92419370Spst v = v1 + v2; 92519370Spst break; 92698944Sobrien 92719370Spst case BINOP_SUB: 92819370Spst v = v1 - v2; 92919370Spst break; 93098944Sobrien 93119370Spst case BINOP_MUL: 93219370Spst v = v1 * v2; 93319370Spst break; 93498944Sobrien 93519370Spst case BINOP_DIV: 93619370Spst v = v1 / v2; 93719370Spst break; 93898944Sobrien 93998944Sobrien case BINOP_EXP: 94098944Sobrien v = pow (v1, v2); 94198944Sobrien if (errno) 942130803Smarcel error ("Cannot perform exponentiation: %s", safe_strerror (errno)); 94398944Sobrien break; 94498944Sobrien 94519370Spst case BINOP_REM: 94619370Spst v = v1 % v2; 94719370Spst break; 94898944Sobrien 94919370Spst case BINOP_MOD: 95019370Spst /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, 95119370Spst v1 mod 0 has a defined value, v1. */ 95219370Spst if (v2 == 0) 95319370Spst { 95419370Spst v = v1; 95519370Spst } 95619370Spst else 95719370Spst { 95898944Sobrien v = v1 / v2; 95919370Spst /* Note floor(v1/v2) == v1/v2 for unsigned. */ 96019370Spst v = v1 - (v2 * v); 96119370Spst } 96219370Spst break; 96398944Sobrien 96419370Spst case BINOP_LSH: 96519370Spst v = v1 << v2; 96619370Spst break; 96798944Sobrien 96819370Spst case BINOP_RSH: 96919370Spst v = v1 >> v2; 97019370Spst break; 97198944Sobrien 97219370Spst case BINOP_BITWISE_AND: 97319370Spst v = v1 & v2; 97419370Spst break; 97598944Sobrien 97619370Spst case BINOP_BITWISE_IOR: 97719370Spst v = v1 | v2; 97819370Spst break; 97998944Sobrien 98019370Spst case BINOP_BITWISE_XOR: 98119370Spst v = v1 ^ v2; 98219370Spst break; 98398944Sobrien 98419370Spst case BINOP_LOGICAL_AND: 98519370Spst v = v1 && v2; 98619370Spst break; 98798944Sobrien 98819370Spst case BINOP_LOGICAL_OR: 98919370Spst v = v1 || v2; 99019370Spst break; 99198944Sobrien 99219370Spst case BINOP_MIN: 99319370Spst v = v1 < v2 ? v1 : v2; 99419370Spst break; 99598944Sobrien 99619370Spst case BINOP_MAX: 99719370Spst v = v1 > v2 ? v1 : v2; 99819370Spst break; 99919370Spst 100019370Spst case BINOP_EQUAL: 100119370Spst v = v1 == v2; 100219370Spst break; 100319370Spst 100498944Sobrien case BINOP_NOTEQUAL: 100598944Sobrien v = v1 != v2; 100698944Sobrien break; 100798944Sobrien 100819370Spst case BINOP_LESS: 100919370Spst v = v1 < v2; 101019370Spst break; 101198944Sobrien 101219370Spst default: 101319370Spst error ("Invalid binary operation on numbers."); 101419370Spst } 101519370Spst 101619370Spst /* This is a kludge to get around the fact that we don't 101719370Spst know how to determine the result type from the types of 101819370Spst the operands. (I'm not really sure how much we feel the 101919370Spst need to duplicate the exact rules of the current 102019370Spst language. They can get really hairy. But not to do so 102119370Spst makes it hard to document just what we *do* do). */ 102219370Spst 102319370Spst /* Can't just call init_type because we wouldn't know what 102419370Spst name to give the type. */ 102519370Spst val = allocate_value 102619370Spst (result_len > TARGET_LONG_BIT / HOST_CHAR_BIT 102719370Spst ? builtin_type_unsigned_long_long 102819370Spst : builtin_type_unsigned_long); 102919370Spst store_unsigned_integer (VALUE_CONTENTS_RAW (val), 103019370Spst TYPE_LENGTH (VALUE_TYPE (val)), 103119370Spst v); 103219370Spst } 103319370Spst else 103419370Spst { 103598944Sobrien LONGEST v1, v2, v = 0; 103619370Spst v1 = value_as_long (arg1); 103719370Spst v2 = value_as_long (arg2); 103898944Sobrien 103919370Spst switch (op) 104019370Spst { 104119370Spst case BINOP_ADD: 104219370Spst v = v1 + v2; 104319370Spst break; 104498944Sobrien 104519370Spst case BINOP_SUB: 104619370Spst v = v1 - v2; 104719370Spst break; 104898944Sobrien 104919370Spst case BINOP_MUL: 105019370Spst v = v1 * v2; 105119370Spst break; 105298944Sobrien 105319370Spst case BINOP_DIV: 105419370Spst v = v1 / v2; 105598944Sobrien break; 105698944Sobrien 105798944Sobrien case BINOP_EXP: 105898944Sobrien v = pow (v1, v2); 105998944Sobrien if (errno) 1060130803Smarcel error ("Cannot perform exponentiation: %s", safe_strerror (errno)); 106119370Spst break; 106298944Sobrien 106319370Spst case BINOP_REM: 106419370Spst v = v1 % v2; 106519370Spst break; 106698944Sobrien 106719370Spst case BINOP_MOD: 106819370Spst /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, 106919370Spst X mod 0 has a defined value, X. */ 107019370Spst if (v2 == 0) 107119370Spst { 107219370Spst v = v1; 107319370Spst } 107419370Spst else 107519370Spst { 107698944Sobrien v = v1 / v2; 107719370Spst /* Compute floor. */ 107819370Spst if (TRUNCATION_TOWARDS_ZERO && (v < 0) && ((v1 % v2) != 0)) 107919370Spst { 108019370Spst v--; 108119370Spst } 108219370Spst v = v1 - (v2 * v); 108319370Spst } 108419370Spst break; 108598944Sobrien 108619370Spst case BINOP_LSH: 108719370Spst v = v1 << v2; 108819370Spst break; 108998944Sobrien 109019370Spst case BINOP_RSH: 109119370Spst v = v1 >> v2; 109219370Spst break; 109398944Sobrien 109419370Spst case BINOP_BITWISE_AND: 109519370Spst v = v1 & v2; 109619370Spst break; 109798944Sobrien 109819370Spst case BINOP_BITWISE_IOR: 109919370Spst v = v1 | v2; 110019370Spst break; 110198944Sobrien 110219370Spst case BINOP_BITWISE_XOR: 110319370Spst v = v1 ^ v2; 110419370Spst break; 110598944Sobrien 110619370Spst case BINOP_LOGICAL_AND: 110719370Spst v = v1 && v2; 110819370Spst break; 110998944Sobrien 111019370Spst case BINOP_LOGICAL_OR: 111119370Spst v = v1 || v2; 111219370Spst break; 111398944Sobrien 111419370Spst case BINOP_MIN: 111519370Spst v = v1 < v2 ? v1 : v2; 111619370Spst break; 111798944Sobrien 111819370Spst case BINOP_MAX: 111919370Spst v = v1 > v2 ? v1 : v2; 112019370Spst break; 112119370Spst 112219370Spst case BINOP_EQUAL: 112319370Spst v = v1 == v2; 112419370Spst break; 112519370Spst 112619370Spst case BINOP_LESS: 112719370Spst v = v1 < v2; 112819370Spst break; 112998944Sobrien 113019370Spst default: 113119370Spst error ("Invalid binary operation on numbers."); 113219370Spst } 113319370Spst 113419370Spst /* This is a kludge to get around the fact that we don't 113519370Spst know how to determine the result type from the types of 113619370Spst the operands. (I'm not really sure how much we feel the 113719370Spst need to duplicate the exact rules of the current 113819370Spst language. They can get really hairy. But not to do so 113919370Spst makes it hard to document just what we *do* do). */ 114019370Spst 114119370Spst /* Can't just call init_type because we wouldn't know what 114219370Spst name to give the type. */ 114319370Spst val = allocate_value 114419370Spst (result_len > TARGET_LONG_BIT / HOST_CHAR_BIT 114519370Spst ? builtin_type_long_long 114619370Spst : builtin_type_long); 114719370Spst store_signed_integer (VALUE_CONTENTS_RAW (val), 114819370Spst TYPE_LENGTH (VALUE_TYPE (val)), 114919370Spst v); 115019370Spst } 115119370Spst } 115219370Spst 115319370Spst return val; 115419370Spst} 115519370Spst 115619370Spst/* Simulate the C operator ! -- return 1 if ARG1 contains zero. */ 115719370Spst 115819370Spstint 115998944Sobrienvalue_logical_not (struct value *arg1) 116019370Spst{ 1161130803Smarcel int len; 1162130803Smarcel char *p; 116319370Spst struct type *type1; 116419370Spst 116519370Spst COERCE_NUMBER (arg1); 116619370Spst type1 = check_typedef (VALUE_TYPE (arg1)); 116719370Spst 116819370Spst if (TYPE_CODE (type1) == TYPE_CODE_FLT) 116919370Spst return 0 == value_as_double (arg1); 117019370Spst 117119370Spst len = TYPE_LENGTH (type1); 117219370Spst p = VALUE_CONTENTS (arg1); 117319370Spst 117419370Spst while (--len >= 0) 117519370Spst { 117619370Spst if (*p++) 117719370Spst break; 117819370Spst } 117919370Spst 118019370Spst return len < 0; 118119370Spst} 118219370Spst 118398944Sobrien/* Perform a comparison on two string values (whose content are not 118498944Sobrien necessarily null terminated) based on their length */ 118598944Sobrien 118698944Sobrienstatic int 118798944Sobrienvalue_strcmp (struct value *arg1, struct value *arg2) 118898944Sobrien{ 118998944Sobrien int len1 = TYPE_LENGTH (VALUE_TYPE (arg1)); 119098944Sobrien int len2 = TYPE_LENGTH (VALUE_TYPE (arg2)); 119198944Sobrien char *s1 = VALUE_CONTENTS (arg1); 119298944Sobrien char *s2 = VALUE_CONTENTS (arg2); 119398944Sobrien int i, len = len1 < len2 ? len1 : len2; 119498944Sobrien 119598944Sobrien for (i = 0; i < len; i++) 119698944Sobrien { 119798944Sobrien if (s1[i] < s2[i]) 119898944Sobrien return -1; 119998944Sobrien else if (s1[i] > s2[i]) 120098944Sobrien return 1; 120198944Sobrien else 120298944Sobrien continue; 120398944Sobrien } 120498944Sobrien 120598944Sobrien if (len1 < len2) 120698944Sobrien return -1; 120798944Sobrien else if (len1 > len2) 120898944Sobrien return 1; 120998944Sobrien else 121098944Sobrien return 0; 121198944Sobrien} 121298944Sobrien 121319370Spst/* Simulate the C operator == by returning a 1 121419370Spst iff ARG1 and ARG2 have equal contents. */ 121519370Spst 121619370Spstint 121798944Sobrienvalue_equal (struct value *arg1, struct value *arg2) 121819370Spst{ 1219130803Smarcel int len; 1220130803Smarcel char *p1, *p2; 122119370Spst struct type *type1, *type2; 122219370Spst enum type_code code1; 122319370Spst enum type_code code2; 122419370Spst 122519370Spst COERCE_NUMBER (arg1); 122619370Spst COERCE_NUMBER (arg2); 122719370Spst 122819370Spst type1 = check_typedef (VALUE_TYPE (arg1)); 122919370Spst type2 = check_typedef (VALUE_TYPE (arg2)); 123019370Spst code1 = TYPE_CODE (type1); 123119370Spst code2 = TYPE_CODE (type2); 123219370Spst 123346283Sdfr if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL) && 123446283Sdfr (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL)) 123519370Spst return longest_to_int (value_as_long (value_binop (arg1, arg2, 123619370Spst BINOP_EQUAL))); 123746283Sdfr else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL) 123846283Sdfr && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL)) 123919370Spst return value_as_double (arg1) == value_as_double (arg2); 124019370Spst 124119370Spst /* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever 124219370Spst is bigger. */ 124346283Sdfr else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL)) 124498944Sobrien return value_as_address (arg1) == (CORE_ADDR) value_as_long (arg2); 124546283Sdfr else if (code2 == TYPE_CODE_PTR && (code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL)) 124698944Sobrien return (CORE_ADDR) value_as_long (arg1) == value_as_address (arg2); 124719370Spst 124819370Spst else if (code1 == code2 124919370Spst && ((len = (int) TYPE_LENGTH (type1)) 125019370Spst == (int) TYPE_LENGTH (type2))) 125119370Spst { 125219370Spst p1 = VALUE_CONTENTS (arg1); 125319370Spst p2 = VALUE_CONTENTS (arg2); 125419370Spst while (--len >= 0) 125519370Spst { 125619370Spst if (*p1++ != *p2++) 125719370Spst break; 125819370Spst } 125919370Spst return len < 0; 126019370Spst } 126198944Sobrien else if (code1 == TYPE_CODE_STRING && code2 == TYPE_CODE_STRING) 126298944Sobrien { 126398944Sobrien return value_strcmp (arg1, arg2) == 0; 126498944Sobrien } 126519370Spst else 126619370Spst { 126719370Spst error ("Invalid type combination in equality test."); 126898944Sobrien return 0; /* For lint -- never reached */ 126919370Spst } 127019370Spst} 127119370Spst 127219370Spst/* Simulate the C operator < by returning 1 127319370Spst iff ARG1's contents are less than ARG2's. */ 127419370Spst 127519370Spstint 127698944Sobrienvalue_less (struct value *arg1, struct value *arg2) 127719370Spst{ 1278130803Smarcel enum type_code code1; 1279130803Smarcel enum type_code code2; 128019370Spst struct type *type1, *type2; 128119370Spst 128219370Spst COERCE_NUMBER (arg1); 128319370Spst COERCE_NUMBER (arg2); 128419370Spst 128519370Spst type1 = check_typedef (VALUE_TYPE (arg1)); 128619370Spst type2 = check_typedef (VALUE_TYPE (arg2)); 128719370Spst code1 = TYPE_CODE (type1); 128819370Spst code2 = TYPE_CODE (type2); 128919370Spst 129046283Sdfr if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL) && 129146283Sdfr (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL)) 129219370Spst return longest_to_int (value_as_long (value_binop (arg1, arg2, 129319370Spst BINOP_LESS))); 129446283Sdfr else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL) 129546283Sdfr && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL)) 129619370Spst return value_as_double (arg1) < value_as_double (arg2); 129719370Spst else if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR) 129898944Sobrien return value_as_address (arg1) < value_as_address (arg2); 129919370Spst 130019370Spst /* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever 130119370Spst is bigger. */ 130246283Sdfr else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL)) 130398944Sobrien return value_as_address (arg1) < (CORE_ADDR) value_as_long (arg2); 130446283Sdfr else if (code2 == TYPE_CODE_PTR && (code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL)) 130598944Sobrien return (CORE_ADDR) value_as_long (arg1) < value_as_address (arg2); 130698944Sobrien else if (code1 == TYPE_CODE_STRING && code2 == TYPE_CODE_STRING) 130798944Sobrien return value_strcmp (arg1, arg2) < 0; 130819370Spst else 130919370Spst { 131019370Spst error ("Invalid type combination in ordering comparison."); 131119370Spst return 0; 131219370Spst } 131319370Spst} 131419370Spst 131519370Spst/* The unary operators - and ~. Both free the argument ARG1. */ 131619370Spst 131798944Sobrienstruct value * 131898944Sobrienvalue_neg (struct value *arg1) 131919370Spst{ 1320130803Smarcel struct type *type; 1321130803Smarcel struct type *result_type = VALUE_TYPE (arg1); 132219370Spst 132319370Spst COERCE_REF (arg1); 132419370Spst COERCE_ENUM (arg1); 132519370Spst 132619370Spst type = check_typedef (VALUE_TYPE (arg1)); 132719370Spst 132819370Spst if (TYPE_CODE (type) == TYPE_CODE_FLT) 132998944Sobrien return value_from_double (result_type, -value_as_double (arg1)); 133046283Sdfr else if (TYPE_CODE (type) == TYPE_CODE_INT || TYPE_CODE (type) == TYPE_CODE_BOOL) 133146283Sdfr { 1332130803Smarcel /* Perform integral promotion for ANSI C/C++. FIXME: What about 1333130803Smarcel FORTRAN and (the deleted) chill ? */ 133446283Sdfr if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int)) 133546283Sdfr result_type = builtin_type_int; 133646283Sdfr 133798944Sobrien return value_from_longest (result_type, -value_as_long (arg1)); 133846283Sdfr } 133998944Sobrien else 134098944Sobrien { 134198944Sobrien error ("Argument to negate operation not a number."); 134298944Sobrien return 0; /* For lint -- never reached */ 134398944Sobrien } 134419370Spst} 134519370Spst 134698944Sobrienstruct value * 134798944Sobrienvalue_complement (struct value *arg1) 134819370Spst{ 1349130803Smarcel struct type *type; 1350130803Smarcel struct type *result_type = VALUE_TYPE (arg1); 135198944Sobrien int typecode; 135246283Sdfr 135319370Spst COERCE_REF (arg1); 135419370Spst COERCE_ENUM (arg1); 135519370Spst 135646283Sdfr type = check_typedef (VALUE_TYPE (arg1)); 135719370Spst 135846283Sdfr typecode = TYPE_CODE (type); 135946283Sdfr if ((typecode != TYPE_CODE_INT) && (typecode != TYPE_CODE_BOOL)) 136046283Sdfr error ("Argument to complement operation not an integer or boolean."); 136146283Sdfr 136246283Sdfr /* Perform integral promotion for ANSI C/C++. 136346283Sdfr FIXME: What about FORTRAN ? */ 136446283Sdfr if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int)) 136546283Sdfr result_type = builtin_type_int; 136646283Sdfr 136798944Sobrien return value_from_longest (result_type, ~value_as_long (arg1)); 136819370Spst} 136919370Spst 137019370Spst/* The INDEX'th bit of SET value whose VALUE_TYPE is TYPE, 137119370Spst and whose VALUE_CONTENTS is valaddr. 137219370Spst Return -1 if out of range, -2 other error. */ 137319370Spst 137419370Spstint 137598944Sobrienvalue_bit_index (struct type *type, char *valaddr, int index) 137619370Spst{ 137719370Spst LONGEST low_bound, high_bound; 137819370Spst LONGEST word; 137919370Spst unsigned rel_index; 138019370Spst struct type *range = TYPE_FIELD_TYPE (type, 0); 138119370Spst if (get_discrete_bounds (range, &low_bound, &high_bound) < 0) 138219370Spst return -2; 138319370Spst if (index < low_bound || index > high_bound) 138419370Spst return -1; 138519370Spst rel_index = index - low_bound; 138619370Spst word = unpack_long (builtin_type_unsigned_char, 138719370Spst valaddr + (rel_index / TARGET_CHAR_BIT)); 138819370Spst rel_index %= TARGET_CHAR_BIT; 138919370Spst if (BITS_BIG_ENDIAN) 139019370Spst rel_index = TARGET_CHAR_BIT - 1 - rel_index; 139119370Spst return (word >> rel_index) & 1; 139219370Spst} 139319370Spst 139498944Sobrienstruct value * 139598944Sobrienvalue_in (struct value *element, struct value *set) 139619370Spst{ 139719370Spst int member; 139819370Spst struct type *settype = check_typedef (VALUE_TYPE (set)); 139919370Spst struct type *eltype = check_typedef (VALUE_TYPE (element)); 140019370Spst if (TYPE_CODE (eltype) == TYPE_CODE_RANGE) 140119370Spst eltype = TYPE_TARGET_TYPE (eltype); 140219370Spst if (TYPE_CODE (settype) != TYPE_CODE_SET) 140319370Spst error ("Second argument of 'IN' has wrong type"); 140419370Spst if (TYPE_CODE (eltype) != TYPE_CODE_INT 140519370Spst && TYPE_CODE (eltype) != TYPE_CODE_CHAR 140619370Spst && TYPE_CODE (eltype) != TYPE_CODE_ENUM 140719370Spst && TYPE_CODE (eltype) != TYPE_CODE_BOOL) 140819370Spst error ("First argument of 'IN' has wrong type"); 140919370Spst member = value_bit_index (settype, VALUE_CONTENTS (set), 141019370Spst value_as_long (element)); 141119370Spst if (member < 0) 141219370Spst error ("First argument of 'IN' not in range"); 141319370Spst return value_from_longest (LA_BOOL_TYPE, member); 141419370Spst} 141519370Spst 141619370Spstvoid 141798944Sobrien_initialize_valarith (void) 141819370Spst{ 141919370Spst} 1420