+2015-01-13 Chung-Ju Wu <jasonwucj@gmail.com>
+
+ * config/nds32/nds32.h (NDS32_SYMBOL_FLAG_RODATA): Define our own
+ target-specific symbol_ref flag.
+ (NDS32_SYMBOL_REF_RODATA_P): Define it to check if the symbol_ref
+ resides in rodata section.
+ * config/nds32/nds32.c (TARGET_ENCODE_SECTION_INFO): Define.
+ (nds32_encode_section_info): New function.
+
2015-01-13 Chung-Ju Wu <jasonwucj@gmail.com>
* config/nds32/nds32.md (call): Use pseudo instruction bal which
return nds32_address_cost_impl (address, mode, as, speed);
}
+\f
+/* Dividing the Output into Sections (Texts, Data, . . . ). */
+
+/* If references to a symbol or a constant must be treated differently
+ depending on something about the variable or function named by the symbol
+ (such as what section it is in), we use this hook to store flags
+ in symbol_ref rtx. */
+static void
+nds32_encode_section_info (tree decl, rtx rtl, int new_decl_p)
+{
+ default_encode_section_info (decl, rtl, new_decl_p);
+
+ /* For the memory rtx, if it references to rodata section, we can store
+ NDS32_SYMBOL_FLAG_RODATA flag into symbol_ref rtx so that the
+ nds32_legitimate_address_p() can determine how to treat such symbol_ref
+ based on -mcmodel=X and this information. */
+ if (MEM_P (rtl) && MEM_READONLY_P (rtl))
+ {
+ rtx addr = XEXP (rtl, 0);
+
+ if (GET_CODE (addr) == SYMBOL_REF)
+ {
+ /* For (mem (symbol_ref X)) case. */
+ SYMBOL_REF_FLAGS (addr) |= NDS32_SYMBOL_FLAG_RODATA;
+ }
+ else if (GET_CODE (addr) == CONST
+ && GET_CODE (XEXP (addr, 0)) == PLUS)
+ {
+ /* For (mem (const (plus (symbol_ref X) (const_int N)))) case. */
+ rtx plus_op = XEXP (addr, 0);
+ rtx op0 = XEXP (plus_op, 0);
+ rtx op1 = XEXP (plus_op, 1);
+
+ if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
+ SYMBOL_REF_FLAGS (op0) |= NDS32_SYMBOL_FLAG_RODATA;
+ }
+ }
+}
+
\f
/* Defining the Output Assembler Language. */
\f
/* Dividing the Output into Sections (Texts, Data, . . . ). */
+#undef TARGET_ENCODE_SECTION_INFO
+#define TARGET_ENCODE_SECTION_INFO nds32_encode_section_info
+
\f
/* Position Independent Code. */
/* The following are auxiliary macros or structure declarations
that are used all over the nds32.c and nds32.h. */
+/* Use SYMBOL_FLAG_MACH_DEP to define our own symbol_ref flag.
+ It is used in nds32_encode_section_info() to store flag in symbol_ref
+ in case the symbol should be placed in .rodata section.
+ So that we can check it in nds32_legitimate_address_p(). */
+#define NDS32_SYMBOL_FLAG_RODATA \
+ (SYMBOL_FLAG_MACH_DEP << 0)
+#define NDS32_SYMBOL_REF_RODATA_P(x) \
+ ((SYMBOL_REF_FLAGS (x) & NDS32_SYMBOL_FLAG_RODATA) != 0)
/* Computing the Length of an Insn. */
#define ADJUST_INSN_LENGTH(INSN, LENGTH) \