📄 xtensa.h
字号:
goto LABEL; \ \ /* check for "register + offset" addressing */ \ if (GET_CODE (xinsn) == PLUS) \ { \ rtx xplus0 = XEXP (xinsn, 0); \ rtx xplus1 = XEXP (xinsn, 1); \ enum rtx_code code0; \ enum rtx_code code1; \ \ while (GET_CODE (xplus0) == SUBREG) \ xplus0 = SUBREG_REG (xplus0); \ code0 = GET_CODE (xplus0); \ \ while (GET_CODE (xplus1) == SUBREG) \ xplus1 = SUBREG_REG (xplus1); \ code1 = GET_CODE (xplus1); \ \ /* swap operands if necessary so the register is first */ \ if (code0 != REG && code1 == REG) \ { \ xplus0 = XEXP (xinsn, 1); \ xplus1 = XEXP (xinsn, 0); \ code0 = GET_CODE (xplus0); \ code1 = GET_CODE (xplus1); \ } \ \ if (code0 == REG && REG_OK_FOR_BASE_P (xplus0) \ && code1 == CONST_INT \ && xtensa_mem_offset (INTVAL (xplus1), (MODE))) \ { \ goto LABEL; \ } \ } \ } while (0)/* A C expression that is 1 if the RTX X is a constant which is a valid address. This is defined to be the same as 'CONSTANT_P (X)', but rejecting CONST_DOUBLE. */#define CONSTANT_ADDRESS_P(X) \ ((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \ || (GET_CODE (X) == CONST)))/* Nonzero if the constant value X is a legitimate general operand. It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */#define LEGITIMATE_CONSTANT_P(X) 1/* A C expression that is nonzero if X is a legitimate immediate operand on the target machine when generating position independent code. */#define LEGITIMATE_PIC_OPERAND_P(X) \ ((GET_CODE (X) != SYMBOL_REF \ || (SYMBOL_REF_LOCAL_P (X) && !SYMBOL_REF_EXTERNAL_P (X))) \ && GET_CODE (X) != LABEL_REF \ && GET_CODE (X) != CONST)/* Tell GCC how to use ADDMI to generate addresses. */#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \ do { \ rtx xinsn = (X); \ if (GET_CODE (xinsn) == PLUS) \ { \ rtx plus0 = XEXP (xinsn, 0); \ rtx plus1 = XEXP (xinsn, 1); \ \ if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG) \ { \ plus0 = XEXP (xinsn, 1); \ plus1 = XEXP (xinsn, 0); \ } \ \ if (GET_CODE (plus0) == REG \ && GET_CODE (plus1) == CONST_INT \ && !xtensa_mem_offset (INTVAL (plus1), MODE) \ && !xtensa_simm8 (INTVAL (plus1)) \ && xtensa_mem_offset (INTVAL (plus1) & 0xff, MODE) \ && xtensa_simm8x256 (INTVAL (plus1) & ~0xff)) \ { \ rtx temp = gen_reg_rtx (Pmode); \ emit_insn (gen_rtx_SET (Pmode, temp, \ gen_rtx_PLUS (Pmode, plus0, \ GEN_INT (INTVAL (plus1) & ~0xff)))); \ (X) = gen_rtx_PLUS (Pmode, temp, \ GEN_INT (INTVAL (plus1) & 0xff)); \ goto WIN; \ } \ } \ } while (0)/* Treat constant-pool references as "mode dependent" since they can only be accessed with SImode loads. This works around a bug in the combiner where a constant pool reference is temporarily converted to an HImode load, which is then assumed to zero-extend based on our definition of LOAD_EXTEND_OP. This is wrong because the high bits of a 16-bit value in the constant pool are now sign-extended by default. */#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \ do { \ if (constantpool_address_p (ADDR)) \ goto LABEL; \ } while (0)/* Specify the machine mode that this machine uses for the index in the tablejump instruction. */#define CASE_VECTOR_MODE (SImode)/* Define this as 1 if 'char' should by default be signed; else as 0. */#define DEFAULT_SIGNED_CHAR 0/* Max number of bytes we can move from memory to memory in one reasonably fast instruction. */#define MOVE_MAX 4#define MAX_MOVE_MAX 4/* Prefer word-sized loads. */#define SLOW_BYTE_ACCESS 1/* Shift instructions ignore all but the low-order few bits. */#define SHIFT_COUNT_TRUNCATED 1/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits is done just by pretending it is already truncated. */#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1/* Specify the machine mode that pointers have. After generation of rtl, the compiler makes no further distinction between pointers and any other objects of this machine mode. */#define Pmode SImode/* A function address in a call instruction is a word address (for indexing purposes) so give the MEM rtx a words's mode. */#define FUNCTION_MODE SImode/* 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 }}, \ {"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 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)/* How to start an assembler comment. */#define ASM_COMMENT_START "#"/* Exception handling TODO!! */#define DWARF_UNWIND_INFO 0/* Xtensa constant pool breaks the devices in crtstuff.c to control section in where code resides. We have to write it as asm code. Use a MOVI and let the assembler relax it -- for the .init and .fini sections, the assembler knows to put the literal in the right place. */#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ asm (SECTION_OP "\n\ movi\ta8, " USER_LABEL_PREFIX #FUNC "\n\ callx8\ta8\n" \ TEXT_SECTION_ASM_OP);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -