⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tc-arm.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
#define INST_IMMEDIATE	0x02000000#define OFFSET_REG	0x02000000#define HWOFFSET_IMM    0x00400000#define SHIFT_BY_REG	0x00000010#define PRE_INDEX	0x01000000#define INDEX_UP	0x00800000#define WRITE_BACK	0x00200000#define LDM_TYPE_2_OR_3	0x00400000#define LITERAL_MASK	0xf000f000#define COND_MASK	0xf0000000#define OPCODE_MASK	0xfe1fffff#define DATA_OP_SHIFT	21/* Codes to distinguish the arithmetic instructions.  */#define OPCODE_AND	0#define OPCODE_EOR	1#define OPCODE_SUB	2#define OPCODE_RSB	3#define OPCODE_ADD	4#define OPCODE_ADC	5#define OPCODE_SBC	6#define OPCODE_RSC	7#define OPCODE_TST	8#define OPCODE_TEQ	9#define OPCODE_CMP	10#define OPCODE_CMN	11#define OPCODE_ORR	12#define OPCODE_MOV	13#define OPCODE_BIC	14#define OPCODE_MVN	15static void do_t_nop		PARAMS ((char *));static void do_t_arit		PARAMS ((char *));static void do_t_add		PARAMS ((char *));static void do_t_asr		PARAMS ((char *));static void do_t_branch9	PARAMS ((char *));static void do_t_branch12	PARAMS ((char *));static void do_t_branch23	PARAMS ((char *));static void do_t_bx		PARAMS ((char *));static void do_t_compare	PARAMS ((char *));static void do_t_ldmstm		PARAMS ((char *));static void do_t_ldr		PARAMS ((char *));static void do_t_ldrb		PARAMS ((char *));static void do_t_ldrh		PARAMS ((char *));static void do_t_lds		PARAMS ((char *));static void do_t_lsl		PARAMS ((char *));static void do_t_lsr		PARAMS ((char *));static void do_t_mov		PARAMS ((char *));static void do_t_push_pop	PARAMS ((char *));static void do_t_str		PARAMS ((char *));static void do_t_strb		PARAMS ((char *));static void do_t_strh		PARAMS ((char *));static void do_t_sub		PARAMS ((char *));static void do_t_swi		PARAMS ((char *));static void do_t_adr		PARAMS ((char *));#define T_OPCODE_MUL 0x4340#define T_OPCODE_TST 0x4200#define T_OPCODE_CMN 0x42c0#define T_OPCODE_NEG 0x4240#define T_OPCODE_MVN 0x43c0#define T_OPCODE_ADD_R3	0x1800#define T_OPCODE_SUB_R3 0x1a00#define T_OPCODE_ADD_HI 0x4400#define T_OPCODE_ADD_ST 0xb000#define T_OPCODE_SUB_ST 0xb080#define T_OPCODE_ADD_SP 0xa800#define T_OPCODE_ADD_PC 0xa000#define T_OPCODE_ADD_I8 0x3000#define T_OPCODE_SUB_I8 0x3800#define T_OPCODE_ADD_I3 0x1c00#define T_OPCODE_SUB_I3 0x1e00#define T_OPCODE_ASR_R	0x4100#define T_OPCODE_LSL_R	0x4080#define T_OPCODE_LSR_R  0x40c0#define T_OPCODE_ASR_I	0x1000#define T_OPCODE_LSL_I	0x0000#define T_OPCODE_LSR_I	0x0800#define T_OPCODE_MOV_I8	0x2000#define T_OPCODE_CMP_I8 0x2800#define T_OPCODE_CMP_LR 0x4280#define T_OPCODE_MOV_HR 0x4600#define T_OPCODE_CMP_HR 0x4500#define T_OPCODE_LDR_PC 0x4800#define T_OPCODE_LDR_SP 0x9800#define T_OPCODE_STR_SP 0x9000#define T_OPCODE_LDR_IW 0x6800#define T_OPCODE_STR_IW 0x6000#define T_OPCODE_LDR_IH 0x8800#define T_OPCODE_STR_IH 0x8000#define T_OPCODE_LDR_IB 0x7800#define T_OPCODE_STR_IB 0x7000#define T_OPCODE_LDR_RW 0x5800#define T_OPCODE_STR_RW 0x5000#define T_OPCODE_LDR_RH 0x5a00#define T_OPCODE_STR_RH 0x5200#define T_OPCODE_LDR_RB 0x5c00#define T_OPCODE_STR_RB 0x5400#define T_OPCODE_PUSH	0xb400#define T_OPCODE_POP	0xbc00#define T_OPCODE_BRANCH 0xe7festatic int thumb_reg		PARAMS ((char ** str, int hi_lo));#define THUMB_SIZE	2	/* Size of thumb instruction.  */#define THUMB_REG_LO	0x1#define THUMB_REG_HI	0x2#define THUMB_REG_ANY	0x3#define THUMB_H1	0x0080#define THUMB_H2	0x0040#define THUMB_ASR 0#define THUMB_LSL 1#define THUMB_LSR 2#define THUMB_MOVE 0#define THUMB_COMPARE 1#define THUMB_LOAD 0#define THUMB_STORE 1#define THUMB_PP_PC_LR 0x0100/* These three are used for immediate shifts, do not alter.  */#define THUMB_WORD 2#define THUMB_HALFWORD 1#define THUMB_BYTE 0struct thumb_opcode{  /* Basic string to match.  */  CONST char * template;  /* Basic instruction code.  */  unsigned long value;  int size;  /* Which CPU variants this exists for.  */  unsigned long variants;  /* Function to call to parse args.  */  void (* parms) PARAMS ((char *));};static CONST struct thumb_opcode tinsns[] ={  {"adc",	0x4140,		2,	ARM_EXT_THUMB, do_t_arit},  {"add",	0x0000,		2,	ARM_EXT_THUMB, do_t_add},  {"and",	0x4000,		2,	ARM_EXT_THUMB, do_t_arit},  {"asr",	0x0000,		2,	ARM_EXT_THUMB, do_t_asr},  {"b",		T_OPCODE_BRANCH, 2,	ARM_EXT_THUMB, do_t_branch12},  {"beq",	0xd0fe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"bne",	0xd1fe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"bcs",	0xd2fe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"bhs",	0xd2fe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"bcc",	0xd3fe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"bul",	0xd3fe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"blo",	0xd3fe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"bmi",	0xd4fe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"bpl",	0xd5fe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"bvs",	0xd6fe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"bvc",	0xd7fe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"bhi",	0xd8fe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"bls",	0xd9fe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"bge",	0xdafe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"blt",	0xdbfe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"bgt",	0xdcfe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"ble",	0xddfe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"bal",	0xdefe,		2,	ARM_EXT_THUMB, do_t_branch9},  {"bic",	0x4380,		2,	ARM_EXT_THUMB, do_t_arit},  {"bl",	0xf7fffffe,	4,	ARM_EXT_THUMB, do_t_branch23},  {"blx",	0,		0,	ARM_EXT_V5, do_t_blx},  {"bkpt",	0xbe00,		2,	ARM_EXT_V5, do_t_bkpt},  {"bx",	0x4700,		2,	ARM_EXT_THUMB, do_t_bx},  {"cmn",	T_OPCODE_CMN,	2,	ARM_EXT_THUMB, do_t_arit},  {"cmp",	0x0000,		2,	ARM_EXT_THUMB, do_t_compare},  {"eor",	0x4040,		2,	ARM_EXT_THUMB, do_t_arit},  {"ldmia",	0xc800,		2,	ARM_EXT_THUMB, do_t_ldmstm},  {"ldr",	0x0000,		2,	ARM_EXT_THUMB, do_t_ldr},  {"ldrb",	0x0000,		2,	ARM_EXT_THUMB, do_t_ldrb},  {"ldrh",	0x0000,		2,	ARM_EXT_THUMB, do_t_ldrh},  {"ldrsb",	0x5600,		2,	ARM_EXT_THUMB, do_t_lds},  {"ldrsh",	0x5e00,		2,	ARM_EXT_THUMB, do_t_lds},  {"ldsb",	0x5600,		2,	ARM_EXT_THUMB, do_t_lds},  {"ldsh",	0x5e00,		2,	ARM_EXT_THUMB, do_t_lds},  {"lsl",	0x0000,		2,	ARM_EXT_THUMB, do_t_lsl},  {"lsr",	0x0000,		2,	ARM_EXT_THUMB, do_t_lsr},  {"mov",	0x0000,		2,	ARM_EXT_THUMB, do_t_mov},  {"mul",	T_OPCODE_MUL,	2,	ARM_EXT_THUMB, do_t_arit},  {"mvn",	T_OPCODE_MVN,	2,	ARM_EXT_THUMB, do_t_arit},  {"neg",	T_OPCODE_NEG,	2,	ARM_EXT_THUMB, do_t_arit},  {"orr",	0x4300,		2,	ARM_EXT_THUMB, do_t_arit},  {"pop",	0xbc00,		2,	ARM_EXT_THUMB, do_t_push_pop},  {"push",	0xb400,		2,	ARM_EXT_THUMB, do_t_push_pop},  {"ror",	0x41c0,		2,	ARM_EXT_THUMB, do_t_arit},  {"sbc",	0x4180,		2,	ARM_EXT_THUMB, do_t_arit},  {"stmia",	0xc000,		2,	ARM_EXT_THUMB, do_t_ldmstm},  {"str",	0x0000,		2,	ARM_EXT_THUMB, do_t_str},  {"strb",	0x0000,		2,	ARM_EXT_THUMB, do_t_strb},  {"strh",	0x0000,		2,	ARM_EXT_THUMB, do_t_strh},  {"swi",	0xdf00,		2,	ARM_EXT_THUMB, do_t_swi},  {"sub",	0x0000,		2,	ARM_EXT_THUMB, do_t_sub},  {"tst",	T_OPCODE_TST,	2,	ARM_EXT_THUMB, do_t_arit},  /* Pseudo ops:  */  {"adr",       0x0000,         2,      ARM_EXT_THUMB, do_t_adr},  {"nop",       0x46C0,         2,      ARM_EXT_THUMB, do_t_nop},      /* mov r8,r8  */};struct reg_entry{  CONST char * name;  int          number;};#define int_register(reg) ((reg) >= 0 && (reg) <= 15)#define cp_register(reg) ((reg) >= 32 && (reg) <= 47)#define fp_register(reg) ((reg) >= 16 && (reg) <= 23)#define REG_PC	15#define REG_LR  14#define REG_SP  13/* These are the standard names.  Users can add aliases with .req.  */static CONST struct reg_entry reg_table[] ={  /* Processor Register Numbers.  */  {"r0", 0},    {"r1", 1},      {"r2", 2},      {"r3", 3},  {"r4", 4},    {"r5", 5},      {"r6", 6},      {"r7", 7},  {"r8", 8},    {"r9", 9},      {"r10", 10},    {"r11", 11},  {"r12", 12},  {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC},  /* APCS conventions.  */  {"a1", 0},	{"a2", 1},    {"a3", 2},     {"a4", 3},  {"v1", 4},	{"v2", 5},    {"v3", 6},     {"v4", 7},     {"v5", 8},  {"v6", 9},	{"sb", 9},    {"v7", 10},    {"sl", 10},  {"fp", 11},	{"ip", 12},   {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC},  /* ATPCS additions to APCS conventions.  */  {"wr", 7},    {"v8", 11},  /* FP Registers.  */  {"f0", 16},   {"f1", 17},   {"f2", 18},   {"f3", 19},  {"f4", 20},   {"f5", 21},   {"f6", 22},   {"f7", 23},  {"c0", 32},   {"c1", 33},   {"c2", 34},   {"c3", 35},  {"c4", 36},   {"c5", 37},   {"c6", 38},   {"c7", 39},  {"c8", 40},   {"c9", 41},   {"c10", 42},  {"c11", 43},  {"c12", 44},  {"c13", 45},  {"c14", 46},  {"c15", 47},  {"cr0", 32},  {"cr1", 33},  {"cr2", 34},  {"cr3", 35},  {"cr4", 36},  {"cr5", 37},  {"cr6", 38},  {"cr7", 39},  {"cr8", 40},  {"cr9", 41},  {"cr10", 42}, {"cr11", 43},  {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},  /* ATPCS additions to float register names.  */  {"s0",16},	{"s1",17},	{"s2",18},	{"s3",19},  {"s4",20},	{"s5",21},	{"s6",22},	{"s7",23},  {"d0",16},	{"d1",17},	{"d2",18},	{"d3",19},  {"d4",20},	{"d5",21},	{"d6",22},	{"d7",23},  /* FIXME: At some point we need to add VFP register names.  */  /* Array terminator.  */  {NULL, 0}};#define BAD_ARGS 	_("Bad arguments to instruction")#define BAD_PC 		_("r15 not allowed here")#define BAD_FLAGS 	_("Instruction should not have flags")#define BAD_COND 	_("Instruction is not conditional")#define ERR_NO_ACCUM	_("acc0 expected")static struct hash_control * arm_ops_hsh   = NULL;static struct hash_control * arm_tops_hsh  = NULL;static struct hash_control * arm_cond_hsh  = NULL;static struct hash_control * arm_shift_hsh = NULL;static struct hash_control * arm_reg_hsh   = NULL;static struct hash_control * arm_psr_hsh   = NULL;/* This table describes all the machine specific pseudo-ops the assembler   has to support.  The fields are:     pseudo-op name without dot     function to call to execute this pseudo-op     Integer arg to pass to the function.  */static void s_req PARAMS ((int));static void s_align PARAMS ((int));static void s_bss PARAMS ((int));static void s_even PARAMS ((int));static void s_ltorg PARAMS ((int));static void s_arm PARAMS ((int));static void s_thumb PARAMS ((int));static void s_code PARAMS ((int));static void s_force_thumb PARAMS ((int));static void s_thumb_func PARAMS ((int));static void s_thumb_set PARAMS ((int));static void arm_s_text PARAMS ((int));static void arm_s_data PARAMS ((int));#ifdef OBJ_ELFstatic void arm_s_section PARAMS ((int));static void s_arm_elf_cons PARAMS ((int));#endifstatic int my_get_expression PARAMS ((expressionS *, char **));CONST pseudo_typeS md_pseudo_table[] ={  /* Never called becasue '.req' does not start line.  */  { "req",         s_req,         0 },  { "bss",         s_bss,         0 },  { "align",       s_align,       0 },  { "arm",         s_arm,         0 },  { "thumb",       s_thumb,       0 },  { "code",        s_code,        0 },  { "force_thumb", s_force_thumb, 0 },  { "thumb_func",  s_thumb_func,  0 },  { "thumb_set",   s_thumb_set,   0 },  { "even",        s_even,        0 },  { "ltorg",       s_ltorg,       0 },  { "pool",        s_ltorg,       0 },  /* Allow for the effect of section changes.  */  { "text",        arm_s_text,    0 },  { "data",        arm_s_data,    0 },#ifdef OBJ_ELF  { "section",     arm_s_section, 0 },  { "section.s",   arm_s_section, 0 },  { "sect",        arm_s_section, 0 },  { "sect.s",      arm_s_section, 0 },  { "word",        s_arm_elf_cons, 4 },  { "long",        s_arm_elf_cons, 4 },  { "file",        dwarf2_directive_file, 0 },  { "loc",         dwarf2_directive_loc,  0 },#else  { "word",        cons, 4},#endif  { "extend",      float_cons, 'x' },  { "ldouble",     float_cons, 'x' },  { "packed",      float_cons, 'p' },  { 0, 0, 0 }};/* Stuff needed to resolve the label ambiguity   As:     ...     label:   <insn>   may differ from:     ...     label:              <insn>*/symbolS *  last_label_seen;static int label_is_thumb_function_name = false;/* Literal stuff.  */#define MAX_LITERAL_POOL_SIZE 1024typedef struct literalS{  struct expressionS exp;  struct arm_it *    inst;} literalT;literalT literals[MAX_LITERAL_POOL_SIZE];/* Next free entry in the pool.  */int next_literal_pool_place = 0;/* Next literal pool number.  */int lit_pool_num = 1;symbolS * current_poolP = NULL;static intadd_to_lit_pool (){  int lit_count = 0;  if (current_poolP == NULL)    current_poolP = symbol_create (FAKE_LABEL_NAME, undefined_section,				   (valueT) 0, &zero_address_frag);  /* Check if this literal value is already in the pool:  */  while (lit_count < next_literal_pool_place)    {      if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op	  && inst.reloc.exp.X_op == O_constant	  && (literals[lit_count].exp.X_add_number	      == inst.reloc.exp.X_add_number)	  && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)	break;      if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op          && inst.reloc.exp.X_op == O_symbol          && (literals[lit_count].exp.X_add_number	      == inst.reloc.exp.X_add_number)          && (literals[lit_count].exp.X_add_symbol	      == inst.reloc.exp.X_add_symbol)          && (literals[lit_count].exp.X_op_symbol	      == inst.reloc.exp.X_op_symbol))        break;      lit_count++;    }  if (lit_count == next_literal_pool_place) /* New entry.  */    {      if (next_literal_pool_place >= MAX_LITERAL_POOL_SIZE)	{	  inst.error = _("Literal Pool Overflow");	  return FAIL;	}      literals[next_literal_pool_place].exp = inst.reloc.exp;      lit_count = next_literal_pool_place++;    }  inst.reloc.exp.X_op = O_symbol;  inst.reloc.exp.X_add_number = (lit_count) * 4 - 8;  inst.reloc.exp.X_add_symbol = current_poolP;  return SUCCESS;}/* Can't use symbol_new here, so have to create a symbol and then at   a later date assign it a value. Thats what these functions do.  */static voidsymbol_locate (symbolP, name, segment, valu, frag)     symbolS *    symbolP;     CONST char * name;		/* It is copied, the caller can modify.  */     segT         segment;	/* Segment identifier (SEG_<something>).  */     valueT       valu;		/* Symbol value.  */     fragS *      frag;		/* Associated fragment.  */{  unsigned int name_length;  char * preserved_copy_of_name;  name_length = strlen (name) + 1;   /* +1 for \0.  */  obstack_grow (&notes, name, name_length);  preserved_copy_of_name = obstack_finish (&notes);#ifdef STRIP_UNDERSCORE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -