📄 valarith.c
字号:
TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT) || (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_FLT && TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_INT)) error ("Argument to arithmetic operation not a number."); if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_FLT || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_FLT) { double v1, v2, v; v1 = value_as_double (arg1); v2 = value_as_double (arg2); switch (op) { case BINOP_ADD: v = v1 + v2; break; case BINOP_SUB: v = v1 - v2; break; case BINOP_MUL: v = v1 * v2; break; case BINOP_DIV: v = v1 / v2; break; default: error ("Integer-only operation on floating point number."); } val = allocate_value (builtin_type_double); SWAP_TARGET_AND_HOST (&v, sizeof (v)); *(double *) VALUE_CONTENTS_RAW (val) = v; } else /* Integral operations here. */ { /* Should we promote to unsigned longest? */ if ((TYPE_UNSIGNED (VALUE_TYPE (arg1)) || TYPE_UNSIGNED (VALUE_TYPE (arg2))) && (TYPE_LENGTH (VALUE_TYPE (arg1)) >= sizeof (unsigned LONGEST) || TYPE_LENGTH (VALUE_TYPE (arg2)) >= sizeof (unsigned LONGEST))) { unsigned LONGEST v1, v2, v; v1 = (unsigned LONGEST) value_as_long (arg1); v2 = (unsigned LONGEST) value_as_long (arg2); switch (op) { case BINOP_ADD: v = v1 + v2; break; case BINOP_SUB: v = v1 - v2; break; case BINOP_MUL: v = v1 * v2; break; case BINOP_DIV: v = v1 / v2; break; case BINOP_REM: v = v1 % v2; break; case BINOP_LSH: v = v1 << v2; break; case BINOP_RSH: v = v1 >> v2; break; case BINOP_LOGAND: v = v1 & v2; break; case BINOP_LOGIOR: v = v1 | v2; break; case BINOP_LOGXOR: v = v1 ^ v2; break; case BINOP_AND: v = v1 && v2; break; case BINOP_OR: v = v1 || v2; break; case BINOP_MIN: v = v1 < v2 ? v1 : v2; break; case BINOP_MAX: v = v1 > v2 ? v1 : v2; break; default: error ("Invalid binary operation on numbers."); } val = allocate_value (BUILTIN_TYPE_UNSIGNED_LONGEST); SWAP_TARGET_AND_HOST (&v, sizeof (v)); *(unsigned LONGEST *) VALUE_CONTENTS_RAW (val) = v; } else { LONGEST v1, v2, v; v1 = value_as_long (arg1); v2 = value_as_long (arg2); switch (op) { case BINOP_ADD: v = v1 + v2; break; case BINOP_SUB: v = v1 - v2; break; case BINOP_MUL: v = v1 * v2; break; case BINOP_DIV: v = v1 / v2; break; case BINOP_REM: v = v1 % v2; break; case BINOP_LSH: v = v1 << v2; break; case BINOP_RSH: v = v1 >> v2; break; case BINOP_LOGAND: v = v1 & v2; break; case BINOP_LOGIOR: v = v1 | v2; break; case BINOP_LOGXOR: v = v1 ^ v2; break; case BINOP_AND: v = v1 && v2; break; case BINOP_OR: v = v1 || v2; break; case BINOP_MIN: v = v1 < v2 ? v1 : v2; break; case BINOP_MAX: v = v1 > v2 ? v1 : v2; break; default: error ("Invalid binary operation on numbers."); } val = allocate_value (BUILTIN_TYPE_LONGEST); SWAP_TARGET_AND_HOST (&v, sizeof (v)); *(LONGEST *) VALUE_CONTENTS_RAW (val) = v; } } return val;}/* Simulate the C operator ! -- return 1 if ARG1 contains zero. */intvalue_zerop (arg1) value arg1;{ register int len; register char *p; COERCE_ARRAY (arg1); if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_FLT) return 0 == value_as_double (arg1); len = TYPE_LENGTH (VALUE_TYPE (arg1)); p = VALUE_CONTENTS (arg1); while (--len >= 0) { if (*p++) break; } return len < 0;}/* Simulate the C operator == by returning a 1 iff ARG1 and ARG2 have equal contents. */intvalue_equal (arg1, arg2) register value arg1, arg2;{ register int len; register char *p1, *p2; enum type_code code1; enum type_code code2; COERCE_ARRAY (arg1); COERCE_ARRAY (arg2); code1 = TYPE_CODE (VALUE_TYPE (arg1)); code2 = TYPE_CODE (VALUE_TYPE (arg2)); if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT) return value_as_long (arg1) == value_as_long (arg2); else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT) && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT)) return value_as_double (arg1) == value_as_double (arg2); /* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever is bigger. */ else if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_INT) return value_as_pointer (arg1) == (CORE_ADDR) value_as_long (arg2); else if (code2 == TYPE_CODE_PTR && code1 == TYPE_CODE_INT) return (CORE_ADDR) value_as_long (arg1) == value_as_pointer (arg2); else if (code1 == code2 && ((len = TYPE_LENGTH (VALUE_TYPE (arg1))) == TYPE_LENGTH (VALUE_TYPE (arg2)))) { p1 = VALUE_CONTENTS (arg1); p2 = VALUE_CONTENTS (arg2); while (--len >= 0) { if (*p1++ != *p2++) break; } return len < 0; } else { error ("Invalid type combination in equality test."); return 0; /* For lint -- never reached */ }}/* Simulate the C operator < by returning 1 iff ARG1's contents are less than ARG2's. */intvalue_less (arg1, arg2) register value arg1, arg2;{ register enum type_code code1; register enum type_code code2; COERCE_ARRAY (arg1); COERCE_ARRAY (arg2); code1 = TYPE_CODE (VALUE_TYPE (arg1)); code2 = TYPE_CODE (VALUE_TYPE (arg2)); if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT) { if (TYPE_UNSIGNED (VALUE_TYPE (arg1)) || TYPE_UNSIGNED (VALUE_TYPE (arg2))) return ((unsigned LONGEST) value_as_long (arg1) < (unsigned LONGEST) value_as_long (arg2)); else return value_as_long (arg1) < value_as_long (arg2); } else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT) && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT)) return value_as_double (arg1) < value_as_double (arg2); else if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR) return value_as_pointer (arg1) < value_as_pointer (arg2); /* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever is bigger. */ else if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_INT) return value_as_pointer (arg1) < (CORE_ADDR) value_as_long (arg2); else if (code2 == TYPE_CODE_PTR && code1 == TYPE_CODE_INT) return (CORE_ADDR) value_as_long (arg1) < value_as_pointer (arg2); else { error ("Invalid type combination in ordering comparison."); return 0; }}/* The unary operators - and ~. Both free the argument ARG1. */valuevalue_neg (arg1) register value arg1;{ register struct type *type; COERCE_ENUM (arg1); type = VALUE_TYPE (arg1); if (TYPE_CODE (type) == TYPE_CODE_FLT) return value_from_double (type, - value_as_double (arg1)); else if (TYPE_CODE (type) == TYPE_CODE_INT) return value_from_longest (type, - value_as_long (arg1)); else { error ("Argument to negate operation not a number."); return 0; /* For lint -- never reached */ }}valuevalue_lognot (arg1) register value arg1;{ COERCE_ENUM (arg1); if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT) error ("Argument to complement operation not an integer."); return value_from_longest (VALUE_TYPE (arg1), ~ value_as_long (arg1));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -