📄 tc-i860.c
字号:
switch (*args) { /* End of args. */ case '\0': if (*s == '\0') match = 1; break; /* These must match exactly. */ case '+': case '(': case ')': case ',': case ' ': if (*s++ == *args) continue; break; /* Must be at least one digit. */ case '#': if (isdigit (*s++)) { while (isdigit (*s)) ++s; continue; } break; /* Next operand must be a register. */ case '1': case '2': case 'd': /* Check for register prefix if necessary. */ if (reg_prefix && *s != reg_prefix) goto error; else s++; switch (*s) { /* Frame pointer. */ case 'f': s++; if (*s++ == 'p') { mask = 0x3; break; } goto error; /* Stack pointer. */ case 's': s++; if (*s++ == 'p') { mask = 0x2; break; } goto error; /* Any register r0..r31. */ case 'r': s++; if (!isdigit (c = *s++)) { goto error; } if (isdigit (*s)) { if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) goto error; } else c -= '0'; mask = c; break; /* Not this opcode. */ default: goto error; } /* Obtained the register, now place it in the opcode. */ switch (*args) { case '1': opcode |= mask << 11; continue; case '2': opcode |= mask << 21; continue; case 'd': opcode |= mask << 16; continue; } break; /* Next operand is a floating point register. */ case 'e': case 'f': case 'g': /* Check for register prefix if necessary. */ if (reg_prefix && *s != reg_prefix) goto error; else s++; if (*s++ == 'f' && isdigit (*s)) { mask = *s++; if (isdigit (*s)) { mask = 10 * (mask - '0') + (*s++ - '0'); if (mask >= 32) { break; } } else mask -= '0'; switch (*args) { case 'e': opcode |= mask << 11; continue; case 'f': opcode |= mask << 21; continue; case 'g': opcode |= mask << 16; if (dual_mode != DUAL_OFF) opcode |= (1 << 9); if (dual_mode == DUAL_DDOT) dual_mode = DUAL_OFF; if (dual_mode == DUAL_ONDDOT) dual_mode = DUAL_ON; if ((opcode & (1 << 10)) && mask != 0 && (mask == ((opcode >> 11) & 0x1f))) as_warn (_("Pipelined instruction: fsrc1 = fdest")); continue; } } break; /* Next operand must be a control register. */ case 'c': /* Check for register prefix if necessary. */ if (reg_prefix && *s != reg_prefix) goto error; else s++; if (strncmp (s, "fir", 3) == 0) { opcode |= 0x0 << 21; s += 3; continue; } if (strncmp (s, "psr", 3) == 0) { opcode |= 0x1 << 21; s += 3; continue; } if (strncmp (s, "dirbase", 7) == 0) { opcode |= 0x2 << 21; s += 7; continue; } if (strncmp (s, "db", 2) == 0) { opcode |= 0x3 << 21; s += 2; continue; } if (strncmp (s, "fsr", 3) == 0) { opcode |= 0x4 << 21; s += 3; continue; } if (strncmp (s, "epsr", 4) == 0) { opcode |= 0x5 << 21; s += 4; continue; } break; /* 5-bit immediate in src1. */ case '5': if (! i860_get_expression (s)) { s = expr_end; the_insn.fup |= OP_IMM_U5; continue; } break; /* 26-bit immediate, relative branch (lbroff). */ case 'l': the_insn.pcrel = 1; the_insn.fup |= OP_IMM_BR26; goto immediate; /* 16-bit split immediate, relative branch (sbroff). */ case 'r': the_insn.pcrel = 1; the_insn.fup |= OP_IMM_BR16; goto immediate; /* 16-bit split immediate. */ case 's': the_insn.fup |= OP_IMM_SPLIT16; goto immediate; /* 16-bit split immediate, byte aligned (st.b). */ case 'S': the_insn.fup |= OP_IMM_SPLIT16; goto immediate; /* 16-bit split immediate, half-word aligned (st.s). */ case 'T': the_insn.fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN2); goto immediate; /* 16-bit split immediate, word aligned (st.l). */ case 'U': the_insn.fup |= (OP_IMM_SPLIT16 | OP_ENCODE1 | OP_ALIGN4); goto immediate; /* 16-bit immediate. */ case 'i': the_insn.fup |= OP_IMM_S16; goto immediate; /* 16-bit immediate, byte aligned (ld.b). */ case 'I': the_insn.fup |= OP_IMM_S16; goto immediate; /* 16-bit immediate, half-word aligned (ld.s). */ case 'J': the_insn.fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN2); goto immediate; /* 16-bit immediate, word aligned (ld.l, {p}fld.l, fst.l). */ case 'K': if (insn->name[0] == 'l') the_insn.fup |= (OP_IMM_S16 | OP_ENCODE1 | OP_ALIGN4); else the_insn.fup |= (OP_IMM_S16 | OP_ENCODE2 | OP_ALIGN4); goto immediate; /* 16-bit immediate, double-word aligned ({p}fld.d, fst.d). */ case 'L': the_insn.fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN8); goto immediate; /* 16-bit immediate, quad-word aligned (fld.q, fst.q). */ case 'M': the_insn.fup |= (OP_IMM_S16 | OP_ENCODE3 | OP_ALIGN16); /*FALLTHROUGH*/ /* Handle the immediate for either the Intel syntax or SVR4 syntax. The Intel syntax is "ha%immediate" whereas SVR4 syntax is "[immediate]@ha". */ immediate:#ifdef SYNTAX_SVR4 if (*s == ' ') s++; /* Note that if i860_get_expression() fails, we will still have created U entries in the symbol table for the 'symbols' in the input string. Try not to create U symbols for registers, etc. */ if (! i860_get_expression (s)) s = expr_end; else goto error; if (strncmp (s, "@ha", 3) == 0) { the_insn.fup |= OP_SEL_HA; s += 3; } else if (strncmp (s, "@h", 2) == 0) { the_insn.fup |= OP_SEL_H; s += 2; } else if (strncmp (s, "@l", 2) == 0) { the_insn.fup |= OP_SEL_L; s += 2; } else if (strncmp (s, "@gotoff", 7) == 0 || strncmp (s, "@GOTOFF", 7) == 0) { as_bad (_("Assembler does not yet support PIC")); the_insn.fup |= OP_SEL_GOTOFF; s += 7; } else if (strncmp (s, "@got", 4) == 0 || strncmp (s, "@GOT", 4) == 0) { as_bad (_("Assembler does not yet support PIC")); the_insn.fup |= OP_SEL_GOT; s += 4; } else if (strncmp (s, "@plt", 4) == 0 || strncmp (s, "@PLT", 4) == 0) { as_bad (_("Assembler does not yet support PIC")); the_insn.fup |= OP_SEL_PLT; s += 4; } the_insn.expand = insn->expand; continue;#else /* ! SYNTAX_SVR4 */ if (*s == ' ') s++; if (strncmp (s, "ha%", 3) == 0) { the_insn.fup |= OP_SEL_HA; s += 3; } else if (strncmp (s, "h%", 2) == 0) { the_insn.fup |= OP_SEL_H; s += 2; } else if (strncmp (s, "l%", 2) == 0) { the_insn.fup |= OP_SEL_L; s += 2; } the_insn.expand = insn->expand; /* Note that if i860_get_expression() fails, we will still have created U entries in the symbol table for the 'symbols' in the input string. Try not to create U symbols for registers, etc. */ if (! i860_get_expression (s)) s = expr_end; else goto error; continue;#endif /* SYNTAX_SVR4 */ break; default: as_fatal (_("failed sanity check.")); } break; } error: if (match == 0) { /* Args don't match. */ if (insn[1].name != NULL && ! strcmp (insn->name, insn[1].name)) { ++insn; s = args_start; continue; } else { as_bad (_("Illegal operands for %s"), insn->name); return; } } break; } the_insn.opcode = opcode;}static inti860_get_expression (str) char *str;{ char *save_in; segT seg; save_in = input_line_pointer; input_line_pointer = str; seg = expression (&the_insn.exp); if (seg != absolute_section && seg != undefined_section && ! SEG_NORMAL (seg)) { the_insn.error = _("bad segment"); expr_end = input_line_pointer; input_line_pointer = save_in; return 1; } expr_end = input_line_pointer; input_line_pointer = save_in; return 0;}/* Turn a string in input_line_pointer into a floating point constant of type TYPE, and store the appropriate bytes in *LITP. The number of LITTLENUMS emitted is stored in *SIZEP. An error message is returned, or NULL on OK. *//* Equal to MAX_PRECISION in atof-ieee.c. */#define MAX_LITTLENUMS 6char *md_atof (type, litP, sizeP) char type; char *litP; int *sizeP;{ int prec; LITTLENUM_TYPE words[MAX_LITTLENUMS]; LITTLENUM_TYPE *wordP; char *t; char *atof_ieee (); switch (type) { case 'f': case 'F': case 's': case 'S': prec = 2; break; case 'd': case 'D': case 'r': case 'R': prec = 4; break; case 'x': case 'X': prec = 6; break; case 'p': case 'P': prec = 6; break; default: *sizeP = 0; return _("Bad call to MD_ATOF()"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -