📄 tc-mcore.c
字号:
as_warn (_("translating bgeni to movi")); } inst &= ~ 0x01f0; inst |= reg << 4; } else as_bad (_("second operand missing")); output = frag_more (2); break; case OBR2: /* like OBR, but arg is 2^n instead of n */ op_end = parse_reg (op_end + 1, & reg); inst |= reg; /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == ',') { op_end = parse_imm (op_end + 1, & reg, 1, 1 << 31); /* Further restrict the immediate to a power of two. */ if ((reg & (reg - 1)) == 0) reg = log2 (reg); else { reg = 0; as_bad (_("immediate is not a power of two")); } /* Immediate values of 0 -> 6 translate to movi. */ if (reg <= 6) { inst = (inst & 0xF) | MCORE_INST_BGENI_ALT; reg = 0x1 << reg; as_warn (_("translating mgeni to movi")); } inst |= reg << 4; } else as_bad (_("second operand missing")); output = frag_more (2); break; case OMa: /* Specific for bmaski: imm 1->7 translate to movi. */ case OMb: case OMc: op_end = parse_reg (op_end + 1, & reg); inst |= reg; /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == ',') { op_end = parse_imm (op_end + 1, & reg, 1, 32); /* Immediate values of 1 -> 7 translate to movi. */ if (reg <= 7) { inst = (inst & 0xF) | MCORE_INST_BMASKI_ALT; reg = (0x1 << reg) - 1; inst |= reg << 4; as_warn (_("translating bmaski to movi")); } else { inst &= ~ 0x01F0; inst |= (reg & 0x1F) << 4; } } else as_bad (_("second operand missing")); output = frag_more (2); break; case SI: op_end = parse_reg (op_end + 1, & reg); inst |= reg; /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == ',') { op_end = parse_imm (op_end + 1, & reg, 1, 31); inst |= reg << 4; } else as_bad (_("second operand missing")); output = frag_more (2); break; case I7: op_end = parse_reg (op_end + 1, & reg); inst |= reg; /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == ',') { op_end = parse_imm (op_end + 1, & reg, 0, 0x7F); inst |= reg << 4; } else as_bad (_("second operand missing")); output = frag_more (2); break; case LS: op_end = parse_reg (op_end + 1, & reg); inst |= reg << 8; /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == ',') { int size; if ((inst & 0x6000) == 0) size = 4; else if ((inst & 0x6000) == 0x4000) size = 2; else if ((inst & 0x6000) == 0x2000) size = 1; op_end = parse_mem (op_end + 1, & reg, & off, size); if (off > 16) as_bad (_("displacement too large (%d)"), off); else inst |= (reg) | (off << 4); } else as_bad (_("second operand missing")); output = frag_more (2); break; case LR: op_end = parse_reg (op_end + 1, & reg); if (reg == 0 || reg == 15) as_bad (_("Invalid register: r0 and r15 illegal")); inst |= (reg << 8); /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == ',') { /* parse_rt calls frag_more() for us. */ input_line_pointer = parse_rt (op_end + 1, & output, 0, 0); op_end = input_line_pointer; } else { as_bad (_("second operand missing")); output = frag_more (2); /* save its space */ } break; case LJ: input_line_pointer = parse_rt (op_end + 1, & output, 1, 0); /* parse_rt() calls frag_more() for us. */ op_end = input_line_pointer; break; case RM: op_end = parse_reg (op_end + 1, & reg); if (reg == 0 || reg == 15) as_bad (_("bad starting register: r0 and r15 invalid")); inst |= reg; /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == '-') { op_end = parse_reg (op_end + 1, & reg); if (reg != 15) as_bad (_("ending register must be r15")); /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; } if (* op_end == ',') { op_end ++; /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == '(') { op_end = parse_reg (op_end + 1, & reg); if (reg != 0) as_bad (_("bad base register: must be r0")); if (* op_end == ')') op_end ++; } else as_bad (_("base register expected")); } else as_bad (_("second operand missing")); output = frag_more (2); break; case RQ: op_end = parse_reg (op_end + 1, & reg); if (reg != 4) as_fatal (_("first register must be r4")); /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == '-') { op_end = parse_reg (op_end + 1, & reg); if (reg != 7) as_fatal (_("last register must be r7")); /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == ',') { op_end ++; /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == '(') { op_end = parse_reg (op_end + 1, & reg); if (reg >= 4 && reg <= 7) as_fatal ("base register cannot be r4, r5, r6, or r7"); inst |= reg; /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == ')') op_end ++; } else as_bad (_("base register expected")); } else as_bad (_("second operand missing")); } else as_bad (_("reg-reg expected")); output = frag_more (2); break; case BR: input_line_pointer = parse_exp (op_end + 1, & e); op_end = input_line_pointer; output = frag_more (2); fix_new_exp (frag_now, output-frag_now->fr_literal, 2, & e, 1, BFD_RELOC_MCORE_PCREL_IMM11BY2); break; case BL: op_end = parse_reg (op_end + 1, & reg); inst |= reg << 4; /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == ',') { op_end = parse_exp (op_end + 1, & e); output = frag_more (2); fix_new_exp (frag_now, output-frag_now->fr_literal, 2, & e, 1, BFD_RELOC_MCORE_PCREL_IMM4BY2); } else { as_bad (_("second operand missing")); output = frag_more (2); } break; case JC: input_line_pointer = parse_exp (op_end + 1, & e); op_end = input_line_pointer; output = frag_var (rs_machine_dependent, md_relax_table[C (COND_JUMP, DISP32)].rlx_length, md_relax_table[C (COND_JUMP, DISP12)].rlx_length, C (COND_JUMP, 0), e.X_add_symbol, e.X_add_number, 0); isize = C32_LEN; break; case JU: input_line_pointer = parse_exp (op_end + 1, & e); op_end = input_line_pointer; output = frag_var (rs_machine_dependent, md_relax_table[C (UNCD_JUMP, DISP32)].rlx_length, md_relax_table[C (UNCD_JUMP, DISP12)].rlx_length, C (UNCD_JUMP, 0), e.X_add_symbol, e.X_add_number, 0); isize = U32_LEN; break; case JL: inst = MCORE_INST_JSRI; /* jsri */ input_line_pointer = parse_rt (op_end + 1, & output, 1, & e); /* parse_rt() calls frag_more for us. */ op_end = input_line_pointer; /* Only do this if we know how to do it ... */ if (e.X_op != O_absent && do_jsri2bsr) { /* Look at adding the R_PCREL_JSRIMM11BY2. */ fix_new_exp (frag_now, output-frag_now->fr_literal, 2, & e, 1, BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2); } break; case RSI: /* SI, but imm becomes 32-imm */ op_end = parse_reg (op_end + 1, & reg); inst |= reg; /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == ',') { op_end = parse_imm (op_end + 1, & reg, 1, 31); reg = 32 - reg; inst |= reg << 4; } else as_bad (_("second operand missing")); output = frag_more (2); break; case DO21: /* O2, dup rd, lit must be 1 */ op_end = parse_reg (op_end + 1, & reg); inst |= reg; inst |= reg << 4; /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == ',') { op_end = parse_imm (op_end + 1, & reg, 1, 31); if (reg != 1) as_bad (_("second operand must be 1")); } else as_bad (_("second operand missing")); output = frag_more (2); break; case SIa: op_end = parse_reg (op_end + 1, & reg); inst |= reg; /* Skip whitespace. */ while (isspace (* op_end)) ++ op_end; if (* op_end == ',') { op_end = parse_imm (op_end + 1, & reg, 1, 31); if (reg == 0) as_bad (_("zero used as immediate value")); inst |= reg << 4; } else as_bad (_("second operand missing")); output = frag_more (2); break; case OPSR: if (cpu == M210) { as_bad (_("M340 specific opcode used when assembling for M210")); break; } op_end = parse_psrmod (op_end + 1, & reg); /* Look for further selectors. */ while (* op_end == ',') { unsigned value; op_end = parse_psrmod (op_end + 1, & value); if (value & reg) as_bad (_("duplicated psr bit specifier")); reg |= value; } if (reg > 8) as_bad (_("`af' must appear alone")); inst |= (reg & 0x7); output = frag_more (2); break; default: as_bad (_("unimplemented opcode \"%s\""), name); } /* Drop whitespace after all the operands have been parsed. */ while (isspace (* op_end)) op_end ++; /* Give warning message if the insn has more operands than required. */ if (strcmp (op_end, opcode->name) && strcmp (op_end, "")) as_warn (_("ignoring operands: %s "), op_end); output[0] = INST_BYTE0 (inst); output[1] = INST_BYTE1 (inst); check_literals (opcode->transfer, isize);}symbolS *md_undefined_symbol (name) char * name;{ return 0;}voidmd_mcore_end (){ dump_literals (0); subseg_set (text_section, 0);}/* Various routines to kill one day. *//* Equal to MAX_PRECISION in atof-ieee.c */#define MAX_LITTLENUMS 6/* 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.*/char *md_atof (type, litP, sizeP) int type; char * litP; int * sizeP;{ int prec; LITTLENUM_TYPE words[MAX_LITTLENUMS]; int i; 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_NTOF()"); } t = atof_ieee (input_line_pointer, type, words); if (t) input_line_pointer = t; *sizeP = prec * sizeof (LITTLENUM_TYPE); if (! target_big_endian) { for (i = prec - 1; i >= 0; i--) { md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE)); litP += sizeof (LITTLENUM_TYPE); } } else for (i = 0; i < prec; i++) { md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE)); litP += sizeof (LITTLENUM_TYPE); } return 0;}CONST char * md_shortopts = "";#define OPTION_JSRI2BSR_ON (OPTION_MD_BASE + 0)#define OPTION_JSRI2BSR_OFF (OPTION_MD_BASE + 1)#define OPTION_SIFILTER_ON (OPTION_MD_BASE + 2)#define OPTION_SIFILTER_OFF (OPTION_MD_BASE + 3)#define OPTION_CPU (OPTION_MD_BASE + 4)#define OPTION_EB (OPTION_MD_BASE + 5)#define OPTION_EL (OPTION_MD_BASE + 6)struct option md_longopts[] ={ { "no-jsri2bsr", no_argument, NULL, OPTION_JSRI2BSR_OFF}, { "jsri2bsr", no_argument, NULL, OPTION_JSRI2BSR_ON}, { "sifilter", no_argument, NULL, OPTION_SIFILTER_ON}, { "no-sifilter", no_argument, NULL, OPTION_SIFILTER_OFF}, { "cpu", required_argument, NULL, OPTION_CPU}, { "EB", no_argument, NULL, OPTION_EB}, { "EL", no_argument, NULL, OPTION_EL}, { NULL, no_argument, NULL, 0}};size_t md_longopts_size = sizeof (md_longopts);intmd_parse_option (c, arg) int c; char * arg;{ int i; char * p; switch (c) { case OPTION_CPU: if (streq (arg, "210")) { cpu = M210; target_big_endian = 1; } else if (streq (arg, "340")) cpu = M340; else as_warn (_("unrecognised cpu type '%s'"), arg); break; case OPTION_EB: target_big_endian = 1; break; case OPTION_EL: target_big_endian = 0; cpu = M340; break; case OPTION_JSRI2BSR_ON: do_jsri2bsr = 1; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -