📄 tc-arm.c
字号:
static int ldst_extend PARAMS ((char **));static int ldst_extend_v4 PARAMS ((char **));static void thumb_add_sub PARAMS ((char *, int));static void insert_reg PARAMS ((const struct reg_entry *, struct hash_control *));static void thumb_shift PARAMS ((char *, int));static void thumb_mov_compare PARAMS ((char *, int));static void build_arm_ops_hsh PARAMS ((void));static void set_constant_flonums PARAMS ((void));static valueT md_chars_to_number PARAMS ((char *, int));static void build_reg_hsh PARAMS ((struct reg_map *));static void insert_reg_alias PARAMS ((char *, int, struct hash_control *));static int create_register_alias PARAMS ((char *, char *));static void output_inst PARAMS ((const char *));static int accum0_required_here PARAMS ((char **));static int ld_mode_required_here PARAMS ((char **));static void do_branch25 PARAMS ((char *));static symbolS * find_real_start PARAMS ((symbolS *));#ifdef OBJ_ELFstatic bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));#endif/* ARM instructions take 4bytes in the object file, Thumb instructions take 2: */#define INSN_SIZE 4/* "INSN<cond> X,Y" where X:bit12, Y:bit16. */#define MAV_MODE1 0x100c/* "INSN<cond> X,Y" where X:bit16, Y:bit12. */#define MAV_MODE2 0x0c10/* "INSN<cond> X,Y" where X:0, Y:bit16. */#define MAV_MODE3 0x1000/* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12. */#define MAV_MODE4 0x0c0010/* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0. */#define MAV_MODE5 0x00100c/* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0. */#define MAV_MODE6 0x00100c05struct asm_opcode{ /* Basic string to match. */ const char * template; /* Basic instruction code. */ unsigned long value; /* Offset into the template where the condition code (if any) will be. If zero, then the instruction is never conditional. */ unsigned cond_offset; /* Which architecture variant provides this instruction. */ unsigned long variant; /* Function to call to parse args. */ void (* parms) PARAMS ((char *));};static const struct asm_opcode insns[] ={ /* Core ARM Instructions. */ {"and", 0xe0000000, 3, ARM_EXT_V1, do_arit}, {"ands", 0xe0100000, 3, ARM_EXT_V1, do_arit}, {"eor", 0xe0200000, 3, ARM_EXT_V1, do_arit}, {"eors", 0xe0300000, 3, ARM_EXT_V1, do_arit}, {"sub", 0xe0400000, 3, ARM_EXT_V1, do_arit}, {"subs", 0xe0500000, 3, ARM_EXT_V1, do_arit}, {"rsb", 0xe0600000, 3, ARM_EXT_V1, do_arit}, {"rsbs", 0xe0700000, 3, ARM_EXT_V1, do_arit}, {"add", 0xe0800000, 3, ARM_EXT_V1, do_arit}, {"adds", 0xe0900000, 3, ARM_EXT_V1, do_arit}, {"adc", 0xe0a00000, 3, ARM_EXT_V1, do_arit}, {"adcs", 0xe0b00000, 3, ARM_EXT_V1, do_arit}, {"sbc", 0xe0c00000, 3, ARM_EXT_V1, do_arit}, {"sbcs", 0xe0d00000, 3, ARM_EXT_V1, do_arit}, {"rsc", 0xe0e00000, 3, ARM_EXT_V1, do_arit}, {"rscs", 0xe0f00000, 3, ARM_EXT_V1, do_arit}, {"orr", 0xe1800000, 3, ARM_EXT_V1, do_arit}, {"orrs", 0xe1900000, 3, ARM_EXT_V1, do_arit}, {"bic", 0xe1c00000, 3, ARM_EXT_V1, do_arit}, {"bics", 0xe1d00000, 3, ARM_EXT_V1, do_arit}, {"tst", 0xe1100000, 3, ARM_EXT_V1, do_cmp}, {"tsts", 0xe1100000, 3, ARM_EXT_V1, do_cmp}, {"tstp", 0xe110f000, 3, ARM_EXT_V1, do_cmp}, {"teq", 0xe1300000, 3, ARM_EXT_V1, do_cmp}, {"teqs", 0xe1300000, 3, ARM_EXT_V1, do_cmp}, {"teqp", 0xe130f000, 3, ARM_EXT_V1, do_cmp}, {"cmp", 0xe1500000, 3, ARM_EXT_V1, do_cmp}, {"cmps", 0xe1500000, 3, ARM_EXT_V1, do_cmp}, {"cmpp", 0xe150f000, 3, ARM_EXT_V1, do_cmp}, {"cmn", 0xe1700000, 3, ARM_EXT_V1, do_cmp}, {"cmns", 0xe1700000, 3, ARM_EXT_V1, do_cmp}, {"cmnp", 0xe170f000, 3, ARM_EXT_V1, do_cmp}, {"mov", 0xe1a00000, 3, ARM_EXT_V1, do_mov}, {"movs", 0xe1b00000, 3, ARM_EXT_V1, do_mov}, {"mvn", 0xe1e00000, 3, ARM_EXT_V1, do_mov}, {"mvns", 0xe1f00000, 3, ARM_EXT_V1, do_mov}, {"ldr", 0xe4100000, 3, ARM_EXT_V1, do_ldst}, {"ldrb", 0xe4500000, 3, ARM_EXT_V1, do_ldst}, {"ldrt", 0xe4300000, 3, ARM_EXT_V1, do_ldstt}, {"ldrbt", 0xe4700000, 3, ARM_EXT_V1, do_ldstt}, {"str", 0xe4000000, 3, ARM_EXT_V1, do_ldst}, {"strb", 0xe4400000, 3, ARM_EXT_V1, do_ldst}, {"strt", 0xe4200000, 3, ARM_EXT_V1, do_ldstt}, {"strbt", 0xe4600000, 3, ARM_EXT_V1, do_ldstt}, {"stmia", 0xe8800000, 3, ARM_EXT_V1, do_ldmstm}, {"stmib", 0xe9800000, 3, ARM_EXT_V1, do_ldmstm}, {"stmda", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm}, {"stmdb", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm}, {"stmfd", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm}, {"stmfa", 0xe9800000, 3, ARM_EXT_V1, do_ldmstm}, {"stmea", 0xe8800000, 3, ARM_EXT_V1, do_ldmstm}, {"stmed", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm}, {"ldmia", 0xe8900000, 3, ARM_EXT_V1, do_ldmstm}, {"ldmib", 0xe9900000, 3, ARM_EXT_V1, do_ldmstm}, {"ldmda", 0xe8100000, 3, ARM_EXT_V1, do_ldmstm}, {"ldmdb", 0xe9100000, 3, ARM_EXT_V1, do_ldmstm}, {"ldmfd", 0xe8900000, 3, ARM_EXT_V1, do_ldmstm}, {"ldmfa", 0xe8100000, 3, ARM_EXT_V1, do_ldmstm}, {"ldmea", 0xe9100000, 3, ARM_EXT_V1, do_ldmstm}, {"ldmed", 0xe9900000, 3, ARM_EXT_V1, do_ldmstm}, {"swi", 0xef000000, 3, ARM_EXT_V1, do_swi},#ifdef TE_WINCE /* XXX This is the wrong place to do this. Think multi-arch. */ {"bl", 0xeb000000, 2, ARM_EXT_V1, do_branch}, {"b", 0xea000000, 1, ARM_EXT_V1, do_branch},#else {"bl", 0xebfffffe, 2, ARM_EXT_V1, do_branch}, {"b", 0xeafffffe, 1, ARM_EXT_V1, do_branch},#endif /* Pseudo ops. */ {"adr", 0xe28f0000, 3, ARM_EXT_V1, do_adr}, {"adrl", 0xe28f0000, 3, ARM_EXT_V1, do_adrl}, {"nop", 0xe1a00000, 3, ARM_EXT_V1, do_empty}, /* ARM 2 multiplies. */ {"mul", 0xe0000090, 3, ARM_EXT_V2, do_mul}, {"muls", 0xe0100090, 3, ARM_EXT_V2, do_mul}, {"mla", 0xe0200090, 3, ARM_EXT_V2, do_mla}, {"mlas", 0xe0300090, 3, ARM_EXT_V2, do_mla}, /* Generic copressor instructions. */ {"cdp", 0xee000000, 3, ARM_EXT_V2, do_cdp}, {"ldc", 0xec100000, 3, ARM_EXT_V2, do_lstc}, {"ldcl", 0xec500000, 3, ARM_EXT_V2, do_lstc}, {"stc", 0xec000000, 3, ARM_EXT_V2, do_lstc}, {"stcl", 0xec400000, 3, ARM_EXT_V2, do_lstc}, {"mcr", 0xee000010, 3, ARM_EXT_V2, do_co_reg}, {"mrc", 0xee100010, 3, ARM_EXT_V2, do_co_reg}, /* ARM 3 - swp instructions. */ {"swp", 0xe1000090, 3, ARM_EXT_V2S, do_swap}, {"swpb", 0xe1400090, 3, ARM_EXT_V2S, do_swap}, /* ARM 6 Status register instructions. */ {"mrs", 0xe10f0000, 3, ARM_EXT_V3, do_mrs}, {"msr", 0xe120f000, 3, ARM_EXT_V3, do_msr}, /* ScottB: our code uses 0xe128f000 for msr. NickC: but this is wrong because the bits 16 through 19 are handled by the PSR_xxx defines above. */ /* ARM 7M long multiplies. */ {"smull", 0xe0c00090, 5, ARM_EXT_V3M, do_mull}, {"smulls", 0xe0d00090, 5, ARM_EXT_V3M, do_mull}, {"umull", 0xe0800090, 5, ARM_EXT_V3M, do_mull}, {"umulls", 0xe0900090, 5, ARM_EXT_V3M, do_mull}, {"smlal", 0xe0e00090, 5, ARM_EXT_V3M, do_mull}, {"smlals", 0xe0f00090, 5, ARM_EXT_V3M, do_mull}, {"umlal", 0xe0a00090, 5, ARM_EXT_V3M, do_mull}, {"umlals", 0xe0b00090, 5, ARM_EXT_V3M, do_mull}, /* ARM Architecture 4. */ {"ldrh", 0xe01000b0, 3, ARM_EXT_V4, do_ldstv4}, {"ldrsh", 0xe01000f0, 3, ARM_EXT_V4, do_ldstv4}, {"ldrsb", 0xe01000d0, 3, ARM_EXT_V4, do_ldstv4}, {"strh", 0xe00000b0, 3, ARM_EXT_V4, do_ldstv4}, /* ARM Architecture 4T. */ /* Note: bx (and blx) are required on V5, even if the processor does not support Thumb. */ {"bx", 0xe12fff10, 2, ARM_EXT_V4T | ARM_EXT_V5, do_bx}, /* ARM Architecture 5T. */ /* Note: blx has 2 variants, so the .value is set dynamically. Only one of the variants has conditional execution. */ {"blx", 0xe0000000, 3, ARM_EXT_V5, do_blx}, {"clz", 0xe16f0f10, 3, ARM_EXT_V5, do_clz}, {"bkpt", 0xe1200070, 0, ARM_EXT_V5, do_bkpt}, {"ldc2", 0xfc100000, 0, ARM_EXT_V5, do_lstc2}, {"ldc2l", 0xfc500000, 0, ARM_EXT_V5, do_lstc2}, {"stc2", 0xfc000000, 0, ARM_EXT_V5, do_lstc2}, {"stc2l", 0xfc400000, 0, ARM_EXT_V5, do_lstc2}, {"cdp2", 0xfe000000, 0, ARM_EXT_V5, do_cdp2}, {"mcr2", 0xfe000010, 0, ARM_EXT_V5, do_co_reg2}, {"mrc2", 0xfe100010, 0, ARM_EXT_V5, do_co_reg2}, /* ARM Architecture 5TExP. */ {"smlabb", 0xe1000080, 6, ARM_EXT_V5ExP, do_smla}, {"smlatb", 0xe10000a0, 6, ARM_EXT_V5ExP, do_smla}, {"smlabt", 0xe10000c0, 6, ARM_EXT_V5ExP, do_smla}, {"smlatt", 0xe10000e0, 6, ARM_EXT_V5ExP, do_smla}, {"smlawb", 0xe1200080, 6, ARM_EXT_V5ExP, do_smla}, {"smlawt", 0xe12000c0, 6, ARM_EXT_V5ExP, do_smla}, {"smlalbb", 0xe1400080, 7, ARM_EXT_V5ExP, do_smlal}, {"smlaltb", 0xe14000a0, 7, ARM_EXT_V5ExP, do_smlal}, {"smlalbt", 0xe14000c0, 7, ARM_EXT_V5ExP, do_smlal}, {"smlaltt", 0xe14000e0, 7, ARM_EXT_V5ExP, do_smlal}, {"smulbb", 0xe1600080, 6, ARM_EXT_V5ExP, do_smul}, {"smultb", 0xe16000a0, 6, ARM_EXT_V5ExP, do_smul}, {"smulbt", 0xe16000c0, 6, ARM_EXT_V5ExP, do_smul}, {"smultt", 0xe16000e0, 6, ARM_EXT_V5ExP, do_smul}, {"smulwb", 0xe12000a0, 6, ARM_EXT_V5ExP, do_smul}, {"smulwt", 0xe12000e0, 6, ARM_EXT_V5ExP, do_smul}, {"qadd", 0xe1000050, 4, ARM_EXT_V5ExP, do_qadd}, {"qdadd", 0xe1400050, 5, ARM_EXT_V5ExP, do_qadd}, {"qsub", 0xe1200050, 4, ARM_EXT_V5ExP, do_qadd}, {"qdsub", 0xe1600050, 5, ARM_EXT_V5ExP, do_qadd}, /* ARM Architecture 5TE. */ {"pld", 0xf450f000, 0, ARM_EXT_V5E, do_pld}, {"ldrd", 0xe00000d0, 3, ARM_EXT_V5E, do_ldrd}, {"strd", 0xe00000f0, 3, ARM_EXT_V5E, do_ldrd}, {"mcrr", 0xec400000, 4, ARM_EXT_V5E, do_co_reg2c}, {"mrrc", 0xec500000, 4, ARM_EXT_V5E, do_co_reg2c}, /* ARM Architecture 5TEJ. */ {"bxj", 0xe12fff20, 3, ARM_EXT_V5J, do_bxj}, /* Core FPA instruction set (V1). */ {"wfs", 0xee200110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl}, {"rfs", 0xee300110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl}, {"wfc", 0xee400110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl}, {"rfc", 0xee500110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl}, {"ldfs", 0xec100100, 3, FPU_FPA_EXT_V1, do_fpa_ldst}, {"ldfd", 0xec108100, 3, FPU_FPA_EXT_V1, do_fpa_ldst}, {"ldfe", 0xec500100, 3, FPU_FPA_EXT_V1, do_fpa_ldst}, {"ldfp", 0xec508100, 3, FPU_FPA_EXT_V1, do_fpa_ldst}, {"stfs", 0xec000100, 3, FPU_FPA_EXT_V1, do_fpa_ldst}, {"stfd", 0xec008100, 3, FPU_FPA_EXT_V1, do_fpa_ldst}, {"stfe", 0xec400100, 3, FPU_FPA_EXT_V1, do_fpa_ldst}, {"stfp", 0xec408100, 3, FPU_FPA_EXT_V1, do_fpa_ldst}, {"mvfs", 0xee008100, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mvfsp", 0xee008120, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mvfsm", 0xee008140, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mvfsz", 0xee008160, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mvfd", 0xee008180, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mvfdp", 0xee0081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mvfdm", 0xee0081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mvfdz", 0xee0081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mvfe", 0xee088100, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mvfep", 0xee088120, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mvfem", 0xee088140, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mvfez", 0xee088160, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mnfs", 0xee108100, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mnfsp", 0xee108120, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mnfsm", 0xee108140, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mnfsz", 0xee108160, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mnfd", 0xee108180, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mnfdp", 0xee1081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mnfdm", 0xee1081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mnfdz", 0xee1081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mnfe", 0xee188100, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mnfep", 0xee188120, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mnfem", 0xee188140, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"mnfez", 0xee188160, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"abss", 0xee208100, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"abssp", 0xee208120, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"abssm", 0xee208140, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"abssz", 0xee208160, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"absd", 0xee208180, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"absdp", 0xee2081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"absdm", 0xee2081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"absdz", 0xee2081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"abse", 0xee288100, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"absep", 0xee288120, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"absem", 0xee288140, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"absez", 0xee288160, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"rnds", 0xee308100, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"rndsp", 0xee308120, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"rndsm", 0xee308140, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"rndsz", 0xee308160, 3, FPU_FPA_EXT_V1, do_fpa_monadic}, {"rndd", 0xee308180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -