/* Return either ORIG or (const:P (minus:P ORIG PIC_BASE)), depending on whether pic_base is NULL or not. */ static inline rtx gen_pic_offset (rtx orig, rtx pic_base) { if (!pic_base) return orig; else return gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, orig, pic_base)); }
/* Return either ORIG or: (const:P (unspec:P [ORIG] UNSPEC_MACHOPIC_OFFSET)) depending on MACHO_DYNAMIC_NO_PIC_P. */ rtx machopic_gen_offset (rtx orig) { if (MACHO_DYNAMIC_NO_PIC_P) return orig; else { /* Play games to avoid marking the function as needing pic if we are being called as part of the cost-estimation process. */ if (current_ir_type () != IR_GIMPLE) crtl->uses_pic_offset_table = 1; orig = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), UNSPEC_MACHOPIC_OFFSET); return gen_rtx_CONST (Pmode, orig); } }
/* Compute the sum of X and Y, making canonicalizations assumed in an address, namely: sum constant integers, surround the sum of two constants with a CONST, put the constant as the second operand, and group the constant on the outermost sum. This routine assumes both inputs are already in canonical form. */ static rtx form_sum (rtx x, rtx y) { machine_mode mode = GET_MODE (x); if (mode == VOIDmode) mode = GET_MODE (y); if (mode == VOIDmode) mode = Pmode; if (CONST_INT_P (x)) return plus_constant (mode, y, INTVAL (x)); else if (CONST_INT_P (y)) return plus_constant (mode, x, INTVAL (y)); else if (CONSTANT_P (x)) std::swap (x, y); if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1))) return form_sum (XEXP (x, 0), form_sum (XEXP (x, 1), y)); /* Note that if the operands of Y are specified in the opposite order in the recursive calls below, infinite recursion will occur. */ if (GET_CODE (y) == PLUS && CONSTANT_P (XEXP (y, 1))) return form_sum (form_sum (x, XEXP (y, 0)), XEXP (y, 1)); /* If both constant, encapsulate sum. Otherwise, just form sum. A constant will have been placed second. */ if (CONSTANT_P (x) && CONSTANT_P (y)) { if (GET_CODE (x) == CONST) x = XEXP (x, 0); if (GET_CODE (y) == CONST) y = XEXP (y, 0); return gen_rtx_CONST (VOIDmode, gen_rtx_PLUS (mode, x, y)); } return gen_rtx_PLUS (mode, x, y); }
static void gen_addr_rtx (enum machine_mode address_mode, rtx symbol, rtx base, rtx index, rtx step, rtx offset, rtx *addr, rtx **step_p, rtx **offset_p) { rtx act_elem; *addr = NULL_RTX; if (step_p) *step_p = NULL; if (offset_p) *offset_p = NULL; if (index) { act_elem = index; if (step) { act_elem = gen_rtx_MULT (address_mode, act_elem, step); if (step_p) *step_p = &XEXP (act_elem, 1); } *addr = act_elem; } if (base && base != const0_rtx) { if (*addr) *addr = simplify_gen_binary (PLUS, address_mode, base, *addr); else *addr = base; } if (symbol) { act_elem = symbol; if (offset) { act_elem = gen_rtx_PLUS (address_mode, act_elem, offset); if (offset_p) *offset_p = &XEXP (act_elem, 1); if (GET_CODE (symbol) == SYMBOL_REF || GET_CODE (symbol) == LABEL_REF || GET_CODE (symbol) == CONST) act_elem = gen_rtx_CONST (address_mode, act_elem); } if (*addr) *addr = gen_rtx_PLUS (address_mode, *addr, act_elem); else *addr = act_elem; } else if (offset) { if (*addr) { *addr = gen_rtx_PLUS (address_mode, *addr, offset); if (offset_p) *offset_p = &XEXP (*addr, 1); } else { *addr = offset; if (offset_p) *offset_p = addr; } } if (!*addr) *addr = const0_rtx; }