📄 tc-sparc.c
字号:
} if (p->name[0] != s[0]) { error_message = _(": unrecognizable v9a or v9b ancillary state register"); goto error; } if (*args == '/' && (p->regnum == 20 || p->regnum == 21)) { error_message = _(": rd on write only ancillary state register"); goto error; } if (p->regnum >= 24 && (insn->architecture & SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A))) { /* %sys_tick and %sys_tick_cmpr are v9bnotv9a */ error_message = _(": unrecognizable v9a ancillary state register"); goto error; } if (*args == '/') opcode |= (p->regnum << 14); else opcode |= (p->regnum << 25); s += len; continue; } else { error_message = _(": unrecognizable v9a or v9b ancillary state register"); goto error; } case 'M': case 'm': if (strncmp (s, "%asr", 4) == 0) { s += 4; if (isdigit ((unsigned char) *s)) { long num = 0; while (isdigit ((unsigned char) *s)) { num = num * 10 + *s - '0'; ++s; } if (current_architecture >= SPARC_OPCODE_ARCH_V9) { if (num < 16 || 31 < num) { error_message = _(": asr number must be between 16 and 31"); goto error; } } else { if (num < 0 || 31 < num) { error_message = _(": asr number must be between 0 and 31"); goto error; } } opcode |= (*args == 'M' ? RS1 (num) : RD (num)); continue; } else { error_message = _(": expecting %asrN"); goto error; } } /* if %asr */ break; case 'I': the_insn.reloc = BFD_RELOC_SPARC_11; goto immediate; case 'j': the_insn.reloc = BFD_RELOC_SPARC_10; goto immediate; case 'X': /* V8 systems don't understand BFD_RELOC_SPARC_5. */ if (SPARC_OPCODE_ARCH_V9_P (max_architecture)) the_insn.reloc = BFD_RELOC_SPARC_5; else the_insn.reloc = BFD_RELOC_SPARC13; /* These fields are unsigned, but for upward compatibility, allow negative values as well. */ goto immediate; case 'Y': /* V8 systems don't understand BFD_RELOC_SPARC_6. */ if (SPARC_OPCODE_ARCH_V9_P (max_architecture)) the_insn.reloc = BFD_RELOC_SPARC_6; else the_insn.reloc = BFD_RELOC_SPARC13; /* These fields are unsigned, but for upward compatibility, allow negative values as well. */ goto immediate; case 'k': the_insn.reloc = /* RELOC_WDISP2_14 */ BFD_RELOC_SPARC_WDISP16; the_insn.pcrel = 1; goto immediate; case 'G': the_insn.reloc = BFD_RELOC_SPARC_WDISP19; the_insn.pcrel = 1; goto immediate; case 'N': if (*s == 'p' && s[1] == 'n') { s += 2; continue; } break; case 'T': if (*s == 'p' && s[1] == 't') { s += 2; continue; } break; case 'z': if (*s == ' ') { ++s; } if (strncmp (s, "%icc", 4) == 0) { s += 4; continue; } break; case 'Z': if (*s == ' ') { ++s; } if (strncmp (s, "%xcc", 4) == 0) { s += 4; continue; } break; case '6': if (*s == ' ') { ++s; } if (strncmp (s, "%fcc0", 5) == 0) { s += 5; continue; } break; case '7': if (*s == ' ') { ++s; } if (strncmp (s, "%fcc1", 5) == 0) { s += 5; continue; } break; case '8': if (*s == ' ') { ++s; } if (strncmp (s, "%fcc2", 5) == 0) { s += 5; continue; } break; case '9': if (*s == ' ') { ++s; } if (strncmp (s, "%fcc3", 5) == 0) { s += 5; continue; } break; case 'P': if (strncmp (s, "%pc", 3) == 0) { s += 3; continue; } break; case 'W': if (strncmp (s, "%tick", 5) == 0) { s += 5; continue; } break; case '\0': /* End of args. */ if (*s == '\0') { match = 1; } break; case '+': if (*s == '+') { ++s; continue; } if (*s == '-') { continue; } break; case '[': /* These must match exactly. */ case ']': case ',': case ' ': if (*s++ == *args) continue; break; case '#': /* Must be at least one digit. */ if (isdigit ((unsigned char) *s++)) { while (isdigit ((unsigned char) *s)) { ++s; } continue; } break; case 'C': /* Coprocessor state register. */ if (strncmp (s, "%csr", 4) == 0) { s += 4; continue; } break; case 'b': /* Next operand is a coprocessor register. */ case 'c': case 'D': if (*s++ == '%' && *s++ == 'c' && isdigit ((unsigned char) *s)) { mask = *s++; if (isdigit ((unsigned char) *s)) { mask = 10 * (mask - '0') + (*s++ - '0'); if (mask >= 32) { break; } } else { mask -= '0'; } switch (*args) { case 'b': opcode |= mask << 14; continue; case 'c': opcode |= mask; continue; case 'D': opcode |= mask << 25; continue; } } break; case 'r': /* next operand must be a register */ case 'O': case '1': case '2': case 'd': if (*s++ == '%') { switch (c = *s++) { case 'f': /* frame pointer */ if (*s++ == 'p') { mask = 0x1e; break; } goto error; case 'g': /* global register */ c = *s++; if (isoctal (c)) { mask = c - '0'; break; } goto error; case 'i': /* in register */ c = *s++; if (isoctal (c)) { mask = c - '0' + 24; break; } goto error; case 'l': /* local register */ c = *s++; if (isoctal (c)) { mask = (c - '0' + 16); break; } goto error; case 'o': /* out register */ c = *s++; if (isoctal (c)) { mask = (c - '0' + 8); break; } goto error; case 's': /* stack pointer */ if (*s++ == 'p') { mask = 0xe; break; } goto error; case 'r': /* any register */ if (!isdigit ((unsigned char) (c = *s++))) { goto error; } /* FALLTHROUGH */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (isdigit ((unsigned char) *s)) { if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) { goto error; } } else { c -= '0'; } mask = c; break; default: goto error; } if ((mask & ~1) == 2 && sparc_arch_size == 64 && no_undeclared_regs && ! globals[mask]) as_bad (_("detected global register use not covered by .register pseudo-op")); /* Got the register, now figure out where it goes in the opcode. */ switch (*args) { case '1': opcode |= mask << 14; continue; case '2': opcode |= mask; continue; case 'd': opcode |= mask << 25; continue; case 'r': opcode |= (mask << 25) | (mask << 14); continue; case 'O': opcode |= (mask << 25) | (mask << 0); continue; } } break; case 'e': /* next operand is a floating point register */ case 'v': case 'V': case 'f': case 'B': case 'R': case 'g': case 'H': case 'J': { char format; if (*s++ == '%' && ((format = *s) == 'f') && isdigit ((unsigned char) *++s)) { for (mask = 0; isdigit ((unsigned char) *s); ++s) { mask = 10 * mask + (*s - '0'); } /* read the number */ if ((*args == 'v' || *args == 'B' || *args == 'H') && (mask & 1)) { break; } /* register must be even numbered */ if ((*args == 'V' || *args == 'R' || *args == 'J') && (mask & 3)) { break; } /* register must be multiple of 4 */ if (mask >= 64) { if (SPARC_OPCODE_ARCH_V9_P (max_architecture)) error_message = _(": There are only 64 f registers; [0-63]"); else error_message = _(": There are only 32 f registers; [0-31]"); goto error; } /* on error */ else if (mask >= 32) { if (SPARC_OPCODE_ARCH_V9_P (max_architecture)) { v9_arg_p = 1; mask -= 31; /* wrap high bit */ } else { error_message = _(": There are only 32 f registers; [0-31]"); goto error; } } } else { break; } /* if not an 'f' register. */ switch (*args) { case 'v': case 'V': case 'e': opcode |= RS1 (mask); continue; case 'f': case 'B': case 'R': opcode |= RS2 (mask); continue; case 'g': case 'H': case 'J': opcode |= RD (mask); continue; } /* Pack it in. */ know (0); break; } /* float arg */ case 'F': if (strncmp (s, "%fsr", 4) == 0) { s += 4; continue; } break; case '0': /* 64 bit immediate (set, setsw, setx insn) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -