-/* Return how many bits covers PIECE EXPR_LIST. */
-
-static int
-decl_piece_bitsize (rtx piece)
-{
- int ret = (int) GET_MODE (piece);
- if (ret)
- return ret;
- gcc_assert (GET_CODE (XEXP (piece, 0)) == CONCAT
- && CONST_INT_P (XEXP (XEXP (piece, 0), 0)));
- return INTVAL (XEXP (XEXP (piece, 0), 0));
-}
-
-/* Return pointer to the location of location note in PIECE EXPR_LIST. */
-
-static rtx *
-decl_piece_varloc_ptr (rtx piece)
-{
- if ((int) GET_MODE (piece))
- return &XEXP (piece, 0);
- else
- return &XEXP (XEXP (piece, 0), 1);
-}
-
-/* Create an EXPR_LIST for location note LOC_NOTE covering BITSIZE bits.
- Next is the chain of following piece nodes. */
-
-static rtx
-decl_piece_node (rtx loc_note, HOST_WIDE_INT bitsize, rtx next)
-{
- if (bitsize <= (int) MAX_MACHINE_MODE)
- return alloc_EXPR_LIST (bitsize, loc_note, next);
- else
- return alloc_EXPR_LIST (0, gen_rtx_CONCAT (VOIDmode,
- GEN_INT (bitsize),
- loc_note), next);
-}
-
-/* Return rtx that should be stored into loc field for
- LOC_NOTE and BITPOS/BITSIZE. */
-
-static rtx
-construct_piece_list (rtx loc_note, HOST_WIDE_INT bitpos,
- HOST_WIDE_INT bitsize)
-{
- if (bitsize != -1)
- {
- loc_note = decl_piece_node (loc_note, bitsize, NULL_RTX);
- if (bitpos != 0)
- loc_note = decl_piece_node (NULL_RTX, bitpos, loc_note);
- }
- return loc_note;
-}
-
-/* This function either modifies location piece list *DEST in
- place (if SRC and INNER is NULL), or copies location piece list
- *SRC to *DEST while modifying it. Location BITPOS is modified
- to contain LOC_NOTE, any pieces overlapping it are removed resp.
- not copied and if needed some padding around it is added.
- When modifying in place, DEST should point to EXPR_LIST where
- earlier pieces cover PIECE_BITPOS bits, when copying SRC points
- to the start of the whole list and INNER points to the EXPR_LIST
- where earlier pieces cover PIECE_BITPOS bits. */
-
-static void
-adjust_piece_list (rtx *dest, rtx *src, rtx *inner,
- HOST_WIDE_INT bitpos, HOST_WIDE_INT piece_bitpos,
- HOST_WIDE_INT bitsize, rtx loc_note)
-{
- int diff;
- bool copy = inner != NULL;
-
- if (copy)
- {
- /* First copy all nodes preceeding the current bitpos. */
- while (src != inner)
- {
- *dest = decl_piece_node (*decl_piece_varloc_ptr (*src),
- decl_piece_bitsize (*src), NULL_RTX);
- dest = &XEXP (*dest, 1);
- src = &XEXP (*src, 1);
- }
- }
- /* Add padding if needed. */
- if (bitpos != piece_bitpos)
- {
- *dest = decl_piece_node (NULL_RTX, bitpos - piece_bitpos,
- copy ? NULL_RTX : *dest);
- dest = &XEXP (*dest, 1);
- }
- else if (*dest && decl_piece_bitsize (*dest) == bitsize)
- {
- gcc_assert (!copy);
- /* A piece with correct bitpos and bitsize already exist,
- just update the location for it and return. */
- *decl_piece_varloc_ptr (*dest) = loc_note;
- return;
- }
- /* Add the piece that changed. */
- *dest = decl_piece_node (loc_note, bitsize, copy ? NULL_RTX : *dest);
- dest = &XEXP (*dest, 1);
- /* Skip over pieces that overlap it. */
- diff = bitpos - piece_bitpos + bitsize;
- if (!copy)
- src = dest;
- while (diff > 0 && *src)
- {
- rtx piece = *src;
- diff -= decl_piece_bitsize (piece);
- if (copy)
- src = &XEXP (piece, 1);
- else
- {
- *src = XEXP (piece, 1);
- free_EXPR_LIST_node (piece);
- }
- }
- /* Add padding if needed. */
- if (diff < 0 && *src)
- {
- if (!copy)
- dest = src;
- *dest = decl_piece_node (NULL_RTX, -diff, copy ? NULL_RTX : *dest);
- dest = &XEXP (*dest, 1);
- }
- if (!copy)
- return;
- /* Finally copy all nodes following it. */
- while (*src)
- {
- *dest = decl_piece_node (*decl_piece_varloc_ptr (*src),
- decl_piece_bitsize (*src), NULL_RTX);
- dest = &XEXP (*dest, 1);
- src = &XEXP (*src, 1);
- }
-}
-