📄 binutils-2.16.1.patch.svn-base
字号:
+ }+ break;++ case 'q': /* VFPU destination control register */+ case 'r': /* VFPU source control register */+ {+ if ((s[0] == '$') && ISDIGIT (s[1]))+ {+ s++;+ regno = 0;+ do+ {+ regno *= 10;+ regno += *s - '0';+ ++s;+ }+ while (ISDIGIT (*s));++ if ((regno < VF_MIN_CR) || (regno > VF_MAX_CR))+ as_bad (_("Invalid VFPU control register number (%d)"),+ regno);++ else if (!((regno >= VF_MIN_VCR) && (regno <= VF_MAX_VCR)))+ as_bad (_("Improper VFPU control register number (%d)"),+ regno);++ switch (*args)+ {+ case 'q':+ ip->insn_opcode |= (regno & VF_MASK_VCD) << VF_SH_VCD;+ break;+ case 'r':+ ip->insn_opcode |= (regno & VF_MASK_VCS) << VF_SH_VCS;+ break;+ }+ }+ else+ {+ as_bad (_("Invalid VFPU control register name (%s)"), s);+ }++ continue;+ }+ break;++ case 'f': /* condition code */+ {+ int cond = 0;+ if (ISDIGIT (s[0]))+ {+ my_getExpression (&imm_expr, s);+ check_absolute_expr (ip, &imm_expr);+ cond = imm_expr.X_add_number;+ if ((cond < VF_MIN_CC) || (cond > VF_MAX_CC))+ as_bad (_("Invalid VFPU condition code (%d)"), cond);+ imm_expr.X_op = O_absent;+ s = expr_end;+ }+ else+ {+ static const char * const vfpu_cond_names[] = {+ "FL", "EQ", "LT", "LE",+ "TR", "NE", "GE", "GT",+ "EZ", "EN", "EI", "ES",+ "NZ", "NN", "NI", "NS" };+ for (cond = VF_MIN_CC; cond <= VF_MAX_CC; cond++)+ {+ if (strncasecmp(vfpu_cond_names[cond], s, 2) == 0)+ break;+ }+ if ((cond < VF_MIN_CC) || (cond > VF_MAX_CC))+ as_bad (_("Invalid VFPU condition code (%s)"), s);++ s += 2;+ }++ args++;+ if ((cond == 0) || (cond == 4))+ {+ }+ else if (cond & 0x8)+ {+ if (*args - '0' < 1)+ as_bad (_("Invalid VFPU condition oparetion"));+ }+ else+ {+ if (*args - '0' < 2)+ as_bad (_("Invalid VFPU condition oparetion"));+ }++ ip->insn_opcode |= (cond & VF_MASK_CC) << VF_SH_CC;+ continue;+ }+ break;++ case 'a': /* constant code */+ {+ int cst = 0;+ if (ISDIGIT (s[0]))+ {+ my_getExpression (&imm_expr, s);+ check_absolute_expr (ip, &imm_expr);+ cst = imm_expr.X_add_number;+ if ((cst < VF_MIN_CONST) || (cst > VF_MAX_CONST))+ {+ as_bad (_("Improper constant code (%d)"), cst);+ cst &= VF_MASK_CONST;+ }+ imm_expr.X_op = O_absent;+ s = expr_end;+ }+ else+ {+ static const char * const vfpu_const_names[] = {+ "", "VFPU_HUGE", "VFPU_SQRT2", "VFPU_SQRT1_2",+ "VFPU_2_SQRTPI", "VFPU_2_PI", "VFPU_1_PI", "VFPU_PI_4",+ "VFPU_PI_2", "VFPU_PI", "VFPU_E", "VFPU_LOG2E",+ "VFPU_LOG10E", "VFPU_LN2", "VFPU_LN10", "VFPU_2PI",+ "VFPU_PI_6", "VFPU_LOG10TWO", "VFPU_LOG2TEN",+ "VFPU_SQRT3_2"};+ for (cst = VF_MIN_CONST; cst <= VF_MAX_CONST; cst++)+ {+ if (strcasecmp(vfpu_const_names[cst], s) == 0)+ break;+ }+ if ((cst < VF_MIN_CONST) || (cst > VF_MAX_CONST))+ as_bad (_("Invalid constant code (%s)"), s);+ else+ s += strlen(vfpu_const_names[cst]);+ }++ ip->insn_opcode |= cst << VF_SH_CONST;+ }+ continue;++ case 'b': /* scale exponent */+ my_getExpression (&imm_expr, s);+ check_absolute_expr (ip, &imm_expr);+ if ((unsigned long) imm_expr.X_add_number > VF_MAX_SCALE)+ {+ as_bad (_("Improper scale (%lu)"),+ (unsigned long) imm_expr.X_add_number);+ imm_expr.X_add_number &= VF_MASK_SCALE;+ }+ ip->insn_opcode |= imm_expr.X_add_number << VF_SH_SCALE;+ imm_expr.X_op = O_absent;+ s = expr_end;+ continue;++ case 'c': /* branch condition code bit */+ my_getExpression (&imm_expr, s);+ check_absolute_expr (ip, &imm_expr);+ if ((unsigned long) imm_expr.X_add_number > VF_MAX_BCOND)+ {+ as_bad (_("Improper condition bit (%lu)"),+ (unsigned long) imm_expr.X_add_number);+ imm_expr.X_add_number &= VF_MASK_BCOND;+ }+ ip->insn_opcode |= imm_expr.X_add_number << VF_SH_BCOND;+ imm_expr.X_op = O_absent;+ s = expr_end;+ continue;++ case 'e': /* move condition code bit */+ my_getExpression (&imm_expr, s);+ check_absolute_expr (ip, &imm_expr);+ if ((unsigned long) imm_expr.X_add_number > VF_MAX_MCOND)+ {+ as_bad (_("Improper condition bit (%lu)"),+ (unsigned long) imm_expr.X_add_number);+ imm_expr.X_add_number &= VF_MASK_MCOND;+ }+ ip->insn_opcode |= imm_expr.X_add_number << VF_SH_MCOND;+ imm_expr.X_op = O_absent;+ s = expr_end;+ continue;++ case 'i': /* wrap exponent */+ my_getExpression (&imm_expr, s);+ check_absolute_expr (ip, &imm_expr);+ if ((unsigned long) imm_expr.X_add_number > VF_MAX_WRAP)+ {+ as_bad (_("Improper wrap (%lu)"),+ (unsigned long) imm_expr.X_add_number);+ imm_expr.X_add_number &= VF_MASK_WRAP;+ }+ ip->insn_opcode |= imm_expr.X_add_number << VF_SH_WRAP;+ imm_expr.X_op = O_absent;+ s = expr_end;+ continue;++ case 'w': /* rotation code */+ if (s[0] == '[')+ {+ char *rot_str = s;+ int rot_idx = 0;+ int rot_neg = 0;+ int rot_sin = 3;+ int rot_cos = 3;+ int rot_err = 0;+ int rot_n;+ int rot_neg_n = 0;+ int rot_sin_n = 0;+ int rot_cos_n = 0;+ int rot_code;++ if ((ip->insn_opcode & VFPU_MASK_DTYPE) == VFPU_PAIR)+ rot_n = 2;+ else if ((ip->insn_opcode & VFPU_MASK_DTYPE) == VFPU_TRIPLE)+ rot_n = 3;+ else if ((ip->insn_opcode & VFPU_MASK_DTYPE) == VFPU_QUAD)+ rot_n = 4;+ else+ rot_n = 0;++ s++;+ while ((s[0] != ']') && (s[0] != '\0'))+ {+ if (s[0] == '-')+ {+ if ((s[1] != 's') && (s[1] != 'S'))+ {+ rot_err = 1;+ break;+ }+ rot_neg = 1;+ rot_neg_n++;+ s++;+ }++ if (s[0] == ',')+ rot_idx++;+ else if ((s[0] == 'c') || (s[0] == 'C'))+ {+ rot_cos = rot_idx;+ rot_cos_n++;+ }+ else if ((s[0] == 's') || (s[0] == 'S'))+ {+ rot_sin = rot_idx;+ rot_sin_n++;+ }+ else if (ISSPACE(s[0]) || (s[0] == '0'))+ ;+ else+ {+ rot_err = 1;+ break;+ }++ s++;+ }++ if (s[0] == ']')+ rot_idx++;+ else+ rot_err = 1;+ s++;++ if ((rot_sin_n == 0) && (rot_cos_n == 0))+ {+ if (rot_n == 2)+ rot_sin = 2;+ else if ((rot_n == 4) || (rot_n == 3))+ rot_err = 1;+ }++ if (rot_cos_n > 1)+ rot_err = 1;++ if (rot_sin_n > 1)+ {+ if (((rot_sin_n + rot_cos_n) != rot_n)+ || ((rot_n == 4) && (rot_cos_n == 0)))+ rot_err = 1;+ }++ if (rot_neg && (rot_neg_n != rot_sin_n))+ rot_err = 1;++ if (rot_sin_n > 1)+ rot_sin = rot_cos;++ if (rot_err || (rot_n != rot_idx))+ as_bad (_("Invalid rotation code (%s)"), rot_str);++ rot_code = ((rot_neg & VF_MASK_ROT_NEG) << VF_SH_ROT_NEG)+ | ((rot_cos & VF_MASK_ROT_COS) << VF_SH_ROT_COS)+ | ((rot_sin & VF_MASK_ROT_SIN) << VF_SH_ROT_SIN);+ ip->insn_opcode |= rot_code << VF_SH_ROT;+ }+ else+ {+ my_getExpression (&imm_expr, s);+ check_absolute_expr (ip, &imm_expr);+ if ((unsigned long) imm_expr.X_add_number > VF_MAX_ROT)+ {+ as_bad (_("Improper rotation code (%lu)"),+ (unsigned long) imm_expr.X_add_number);+ imm_expr.X_add_number &= VF_MASK_ROT;+ }+ ip->insn_opcode |= imm_expr.X_add_number << VF_SH_ROT;+ imm_expr.X_op = O_absent;+ s = expr_end;+ }+ continue;++ case 'u': /* half float */+ if ((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X')))+ {+ my_getExpression (&imm_expr, s);+ check_absolute_expr (ip, &imm_expr);+ if ((unsigned long) imm_expr.X_add_number > VF_MAX_HFLOAT)+ {+ as_bad (_("Improper half floating point constant: (%lu)"),+ (unsigned long) imm_expr.X_add_number);+ imm_expr.X_add_number &= VF_MASK_HFLOAT;+ }+ ip->insn_opcode |= imm_expr.X_add_number << VF_SH_HFLOAT;+ imm_expr.X_op = O_absent;+ s = expr_end;+ continue;+ }+ else+ {+ char *save_in;+ char *err;+ int len;+ unsigned int length;+ unsigned char temp[8];+ unsigned int f32, f16;+ int exponent32, exponent16;+ int fraction32, fraction16;+ int sign;+ char f16_str[8];++ save_in = input_line_pointer;+ input_line_pointer = s;+ err = md_atof ('f', (char *) temp, &len);+ length = len;+ s = input_line_pointer;+ input_line_pointer = save_in;+ if (err != NULL && *err != '\0')+ {+ as_bad (_("Bad half floating point constant: %s"), err);+ memset (temp, '\0', sizeof temp);+ length = 4;+ }++ if (! target_big_endian)+ f32 = bfd_getl32 (temp);+ else+ f32 = bfd_getb32 (temp);++ sign = (f32 >> VF_SH_F32_SIGN) & VF_MASK_F32_SIGN;+ exponent32 = (f32 >> VF_SH_F32_EXP) & VF_MASK_F32_EXP;+ fraction32 = (f32 >> VF_SH_F32_FRA) & VF_MASK_F32_FRA;+ exponent16 = exponent32+ - VF_BIAS_F32_EXP + VF_BIAS_F16_EXP;++ if (exponent16 < VF_MIN_F16_EXP)+ {+ if ((exponent32 == VF_MIN_F32_EXP)+ && (fraction32 == 0))+ { // zero+ exponent16 = VF_MIN_F16_EXP;+ fraction16 = 0;+ }+ else+ { // underflow+ float* p;+ p = (float*) &f32;+ as_warn (_("Half floating point underflow: %g"),+ *p);+ exponent16 = VF_MIN_F16_EXP;+ fraction16 = 0;+ }+ }+ else if (exponent16 > VF_MAX_F16_EXP)+ {+ if (exponent32 != VF_MAX_F32_EXP)+ { // overflow+ as_warn (_("Half floating point overflow: %g"),+ *(float *)&f32);+ exponent16 = VF_MAX_F16_EXP;+ fraction16 = 0;+ }+ else+ {+ if (fraction32 == 0)+ { // infinity+ exponent16 = VF_MAX_F16_EXP;+ fraction16 = 0;+ }+ else+ { // NaN+ exponent16 = VF_MAX_F16_EXP;+ fraction16 = 1;+ }+ }+ }+ else+ {+ fraction16 = (f32 >> (VF_SH_F32_EXP - VF_SH_F16_EXP))+ & VF_MASK_F16_FRA;+ }++ f16 = (sign << VF_SH_F16_SIGN)+ | (exponent16 << VF_SH_F16_EXP)+ | (fraction16 << VF_SH_F16_FRA);+ ip->insn_opcode |= (f16 & VF_MASK_HFLOAT) << VF_SH_HFLOAT;++ sprintf(f16_str, "0x%04x", f16);+ my_getExpression (&imm_expr, f16_str);++ continue;+ }+ break;++ case 'z': /* read/write access code */+ {+ int rwb = 0;++ if (strncasecmp (s, "WT", 2) == 0)+ rwb = 0x0;+ else if (strncasecmp (s, "WB", 2) == 0)+ rwb = 0x1;+ else+ as_bad (_("Invalid memory access type (%s)"), s);++ s += 2;+ ip->insn_opcode |= (rwb & VF_MASK_RWB) << VF_SH_RWB;++ continue;+ }++ case '0': /* source or target prefix code (X) */+ case '1': /* source or target prefix code (Y) */+ case '2': /* source or target prefix code (Z) */+ case '3': /* source or target prefix code (W) */+ {+ int operand;+ int shift;++ int pfx_neg = 0;+ int pfx_cst = 0;+ int pfx_abs = 0;+ int pfx_swz = 0;+ int pfx_err = 0;+ int cst = 0;+ char *pfx_str = s;++ if (s[0] == '-')+ { // sign code+ pfx_neg = 1;+ s++;+ }+ + if (ISDIGIT (s[0]))+ { // constant+ pfx_cst = 1;++ if (s[0] == '0')+ cst = 0;+ else if (s[0] == '1')+ {+ if (s[1] == '/')+ {+ s += 2;+ if (s[0] == '2')
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -