📄 xtensa.h
字号:
return 5; \ case CONST_DOUBLE: \ return 7;/* Costs of various Xtensa operations. */#define RTX_COSTS(X, CODE, OUTER_CODE) \ case MEM: \ { \ int num_words = \ (GET_MODE_SIZE (GET_MODE (X)) > UNITS_PER_WORD) ? 2 : 1; \ if (memory_address_p (GET_MODE (X), XEXP ((X), 0))) \ return COSTS_N_INSNS (num_words); \ \ return COSTS_N_INSNS (2*num_words); \ } \ \ case FFS: \ return COSTS_N_INSNS (TARGET_NSA ? 5 : 50); \ \ case NOT: \ return COSTS_N_INSNS ((GET_MODE (X) == DImode) ? 3 : 2); \ \ case AND: \ case IOR: \ case XOR: \ if (GET_MODE (X) == DImode) return COSTS_N_INSNS (2); \ return COSTS_N_INSNS (1); \ \ case ASHIFT: \ case ASHIFTRT: \ case LSHIFTRT: \ if (GET_MODE (X) == DImode) return COSTS_N_INSNS (50); \ return COSTS_N_INSNS (1); \ \ case ABS: \ { \ enum machine_mode xmode = GET_MODE (X); \ if (xmode == SFmode) \ return COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50); \ if (xmode == DFmode) \ return COSTS_N_INSNS (50); \ return COSTS_N_INSNS (4); \ } \ \ case PLUS: \ case MINUS: \ { \ enum machine_mode xmode = GET_MODE (X); \ if (xmode == SFmode) \ return COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50); \ if (xmode == DFmode || xmode == DImode) \ return COSTS_N_INSNS (50); \ return COSTS_N_INSNS (1); \ } \ \ case NEG: \ return COSTS_N_INSNS ((GET_MODE (X) == DImode) ? 4 : 2); \ \ case MULT: \ { \ enum machine_mode xmode = GET_MODE (X); \ if (xmode == SFmode) \ return COSTS_N_INSNS (TARGET_HARD_FLOAT ? 4 : 50); \ if (xmode == DFmode || xmode == DImode) \ return COSTS_N_INSNS (50); \ if (TARGET_MUL32) \ return COSTS_N_INSNS (4); \ if (TARGET_MAC16) \ return COSTS_N_INSNS (16); \ if (TARGET_MUL16) \ return COSTS_N_INSNS (12); \ return COSTS_N_INSNS (50); \ } \ \ case DIV: \ case MOD: \ { \ enum machine_mode xmode = GET_MODE (X); \ if (xmode == SFmode) \ return COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV ? 8 : 50); \ if (xmode == DFmode) \ return COSTS_N_INSNS (50); \ } \ /* fall through */ \ \ case UDIV: \ case UMOD: \ { \ enum machine_mode xmode = GET_MODE (X); \ if (xmode == DImode) \ return COSTS_N_INSNS (50); \ if (TARGET_DIV32) \ return COSTS_N_INSNS (32); \ return COSTS_N_INSNS (50); \ } \ \ case SQRT: \ if (GET_MODE (X) == SFmode) \ return COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT ? 8 : 50); \ return COSTS_N_INSNS (50); \ \ case SMIN: \ case UMIN: \ case SMAX: \ case UMAX: \ return COSTS_N_INSNS (TARGET_MINMAX ? 1 : 50); \ \ case SIGN_EXTRACT: \ case SIGN_EXTEND: \ return COSTS_N_INSNS (TARGET_SEXT ? 1 : 2); \ \ case ZERO_EXTRACT: \ case ZERO_EXTEND: \ return COSTS_N_INSNS (1);/* An expression giving the cost of an addressing mode that contains ADDRESS. */#define ADDRESS_COST(ADDR) 1/* A C expression for the cost of moving data from a register in class FROM to one in class TO. The classes are expressed using the enumeration values such as 'GENERAL_REGS'. A value of 2 is the default; other values are interpreted relative to that. */#define REGISTER_MOVE_COST(MODE, FROM, TO) \ (((FROM) == (TO) && (FROM) != BR_REGS && (TO) != BR_REGS) \ ? 2 \ : (reg_class_subset_p ((FROM), AR_REGS) \ && reg_class_subset_p ((TO), AR_REGS) \ ? 2 \ : (reg_class_subset_p ((FROM), AR_REGS) \ && (TO) == ACC_REG \ ? 3 \ : ((FROM) == ACC_REG \ && reg_class_subset_p ((TO), AR_REGS) \ ? 3 \ : 10))))#define MEMORY_MOVE_COST(MODE, CLASS, IN) 4#define BRANCH_COST 3/* Optionally define this if you have added predicates to 'MACHINE.c'. This macro is called within an initializer of an array of structures. The first field in the structure is the name of a predicate and the second field is an array of rtl codes. For each predicate, list all rtl codes that can be in expressions matched by the predicate. The list should have a trailing comma. */#define PREDICATE_CODES \ {"add_operand", { REG, CONST_INT, SUBREG }}, \ {"arith_operand", { REG, CONST_INT, SUBREG }}, \ {"nonimmed_operand", { REG, SUBREG, MEM }}, \ {"mem_operand", { MEM }}, \ {"mask_operand", { REG, CONST_INT, SUBREG }}, \ {"extui_fldsz_operand", { CONST_INT }}, \ {"sext_fldsz_operand", { CONST_INT }}, \ {"lsbitnum_operand", { CONST_INT }}, \ {"fpmem_offset_operand", { CONST_INT }}, \ {"sext_operand", { REG, SUBREG, MEM }}, \ {"branch_operand", { REG, CONST_INT, SUBREG }}, \ {"ubranch_operand", { REG, CONST_INT, SUBREG }}, \ {"call_insn_operand", { CONST_INT, CONST, SYMBOL_REF, REG }}, \ {"move_operand", { REG, SUBREG, MEM, CONST_INT, CONST_DOUBLE, \ CONST, SYMBOL_REF, LABEL_REF }}, \ {"non_const_move_operand", { REG, SUBREG, MEM }}, \ {"const_float_1_operand", { CONST_DOUBLE }}, \ {"branch_operator", { EQ, NE, LT, GE }}, \ {"ubranch_operator", { LTU, GEU }}, \ {"boolean_operator", { EQ, NE }},/* Control the assembler format that we output. *//* How to refer to registers in assembler output. This sequence is indexed by compiler's hard-register-number (see above). */#define REGISTER_NAMES \{ \ "a0", "sp", "a2", "a3", "a4", "a5", "a6", "a7", \ "a8", "a9", "a10", "a11", "a12", "a13", "a14", "a15", \ "fp", "argp", "b0", \ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ "acc" \}/* If defined, a C initializer for an array of structures containing a name and a register number. This macro defines additional names for hard registers, thus allowing the 'asm' option in declarations to refer to registers using alternate names. */#define ADDITIONAL_REGISTER_NAMES \{ \ { "a1", 1 + GP_REG_FIRST } \}#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)/* Recognize machine-specific patterns that may appear within constants. Used for PIC-specific UNSPECs. */#define OUTPUT_ADDR_CONST_EXTRA(STREAM, X, FAIL) \ do { \ if (flag_pic && GET_CODE (X) == UNSPEC && XVECLEN ((X), 0) == 1) \ { \ switch (XINT ((X), 1)) \ { \ case UNSPEC_PLT: \ output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \ fputs ("@PLT", (STREAM)); \ break; \ default: \ goto FAIL; \ } \ break; \ } \ else \ goto FAIL; \ } while (0)/* Globalizing directive for a label. */#define GLOBAL_ASM_OP "\t.global\t"/* Declare an uninitialized external linkage data object. */#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)/* This is how to output an element of a case-vector that is absolute. */#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \ fprintf (STREAM, "%s%sL%u\n", integer_asm_op (4, TRUE), \ LOCAL_LABEL_PREFIX, VALUE)/* This is how to output an element of a case-vector that is relative. This is used for pc-relative code. */#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \ do { \ fprintf (STREAM, "%s%sL%u-%sL%u\n", integer_asm_op (4, TRUE), \ LOCAL_LABEL_PREFIX, (VALUE), \ LOCAL_LABEL_PREFIX, (REL)); \ } while (0)/* This is how to output an assembler line that says to advance the location counter to a multiple of 2**LOG bytes. */#define ASM_OUTPUT_ALIGN(STREAM, LOG) \ do { \ if ((LOG) != 0) \ fprintf (STREAM, "\t.align\t%d\n", 1 << (LOG)); \ } while (0)/* Indicate that jump tables go in the text section. This is necessary when compiling PIC code. */#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)/* Define this macro for the rare case where the RTL needs some sort of machine-dependent fixup immediately before register allocation is done. If the stack frame size is too big to fit in the immediate field of the ENTRY instruction, we need to store the frame size in the constant pool. However, the code in xtensa_function_prologue runs too late to be able to add anything to the constant pool. Since the final frame size isn't known until reload is complete, this seems like the best place to do it. There may also be some fixup required if there is an incoming argument in a7 and the function requires a frame pointer. */#define MACHINE_DEPENDENT_REORG(INSN) xtensa_reorg (INSN)/* Define the strings to put out for each section in the object file. */#define TEXT_SECTION_ASM_OP "\t.text"#define DATA_SECTION_ASM_OP "\t.data"#define BSS_SECTION_ASM_OP "\t.section\t.bss"/* Define output to appear before the constant pool. If the function has been assigned to a specific ELF section, or if it goes into a unique section, set the name of that section to be the literal prefix. */#define ASM_OUTPUT_POOL_PROLOGUE(FILE, FUNNAME, FUNDECL, SIZE) \ do { \ tree fnsection; \ resolve_unique_section ((FUNDECL), 0, flag_function_sections); \ fnsection = DECL_SECTION_NAME (FUNDECL); \ if (fnsection != NULL_TREE) \ { \ const char *fnsectname = TREE_STRING_POINTER (fnsection); \ fprintf (FILE, "\t.begin\tliteral_prefix %s\n", \ strcmp (fnsectname, ".text") ? fnsectname : ""); \ } \ if ((SIZE) > 0) \ { \ function_section (FUNDECL); \ fprintf (FILE, "\t.literal_position\n"); \ } \ } while (0)/* Define code to write out the ".end literal_prefix" directive for a function in a special section. This is appended to the standard ELF code for ASM_DECLARE_FUNCTION_SIZE. */#define XTENSA_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ if (DECL_SECTION_NAME (DECL) != NULL_TREE) \ fprintf (FILE, "\t.end\tliteral_prefix\n")/* A C statement (with or without semicolon) to output a constant in the constant pool, if it needs special treatment. */#define ASM_OUTPUT_SPECIAL_POOL_ENTRY(FILE, X, MODE, ALIGN, LABELNO, JUMPTO) \ do { \ xtensa_output_literal (FILE, X, MODE, LABELNO); \ goto JUMPTO; \ } while (0)/* Store in OUTPUT a string (made with alloca) containing an assembler-name for a local static variable named NAME. LABELNO is an integer which is different for each call. */#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ do { \ (OUTPUT) = (char *) alloca (strlen (NAME) + 10); \ sprintf ((OUTPUT), "%s.%u", (NAME), (LABELNO)); \ } while (0)/* How to start an assembler comment. */#define ASM_COMMENT_START "#"/* Exception handling TODO!! */#define DWARF_UNWIND_INFO 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -