AVR: Support [[len=<words]] notes in inline asm to specifty its size.

This patch adds support for [[len=<words>]] in (the comments of) inline
asm constructs.  It serves several purposes:

- Cases where the expanded asm is longer than determined from the number
  of physical and logical line breaks.  Such cases can lead to errors
  when a jump that uses a too optimistic jump offset is crossing an asm.

- Better code generation for jumps that are crossing an asm.  The default
  length of an asm is (1 + NL) * 2 words, where NL denotes the sum of
  physical and logical line breaks.  However, almost all AVR instructions
  occupy only one 16-bit word.

The feature is implemented in ADJUST_INSN_LENGTH.  The length of
an asm is the sum over all [[len=<words>]] notes, except when an
unrecognized construct is found or an error occurred.  In the latter
case, the default insn length is used.  These <words> are supported:

<words> = [0-9]+
   Specifies a non-negative decimal integer.

<words> = %[0-9]+
<words> = %[<name>]   # Already resolved to %[0-9]+ by the middle-end.
   Refers to the respective asm operand, which must be CONST_INT.

<words> = lds
<words> = sts
   Specifies the length of a LDS or STS instruction, i.e.
   1 word if AVR_TINY, and 2 words otherwise.

<words> = %~
<words> = %~call
<words> = %~jmp
   Specifies the length of a %~call resp. %~jmp instruction, i.e.
   2 words if AVR_HAVE_JMP_CALL, and 1 word otherwise.

In order to observe the assigned lengths, see -fdump-rtl-shorten or the
";; ADDR = ..." insn addresses in the asm output with -mlog=insn_addresses.

The benefits of using magic comments are:

- The feature is backwards compatible, and the target code can use
  the same asm syntax since only asm comments have to be adjusted.
  No #ifdef feature test macros are needed.  The only case where the
  feature is not fully backwards compatible is when asm templates
  already contain invalid "[[len=" notes for some reason.  In that
  case, -mno-asm-len-notes restores the old behavior.

- Since the asm size is the sum over all notes, the final size can
  be stitched together from multiple annotations / parts of an asm
  template, and there is no need to support operations like plus.

gcc/
	* config/avr/avr.cc (avr_read_number, avr_length_of_asm)
	(avr_maybe_length_of_asm): New static functions.
	(avr_adjust_insn_length): Call avr_maybe_length_of_asm on
	unrecognized insns.
	* config/avr/avr.opt (-masm-len-notes, -Wasm-len-notes): New
	options.
	* doc/invoke.texi (AVR Options): Add -masm-len-notes,
	-Wasm-len-notes.
	* doc/extend.texi (Size of an asm): Add @subsubheading
	"Specifying the size of an asm on AVR".

libgcc/config/avr/libf7/
	* libf7.h: Add "[len=...]]" notes to all non-empty inline asm's.
	* libf7.c: Dito.
6 files changed