+2010-11-04 Alan Modra <amodra@gmail.com>
+
+ * config/tc-ppc.c (nop_limit): New var.
+ (OPTION_NOPS): Define.
+ (md_longopts): Add --nops.
+ (md_parse_option): Handle it.
+ (md_show_usage): Publish.
+ (ppc_handle_align): Pad with a branch followed by nops if more
+ than nop_limit nops.
+
2010-11-03 H.J. Lu <hongjiu.lu@intel.com>
PR gas/12186
/* The dwarf2 data alignment, adjusted for 32 or 64 bit. */
int ppc_cie_data_alignment;
+/* More than this number of nops in an alignment op gets a branch
+ instead. */
+unsigned long nop_limit = 4;
+
/* The type of processor we are assembling for. This is one or more
of the PPC_OPCODE flags defined in opcode/ppc.h. */
ppc_cpu_t ppc_cpu = 0;
#else
const char *const md_shortopts = "um:";
#endif
+#define OPTION_NOPS (OPTION_MD_BASE + 0)
const struct option md_longopts[] = {
+ {"nops", required_argument, NULL, OPTION_NOPS},
{NULL, no_argument, NULL, 0}
};
const size_t md_longopts_size = sizeof (md_longopts);
break;
#endif
+ case OPTION_NOPS:
+ {
+ char *end;
+ nop_limit = strtoul (optarg, &end, 0);
+ if (*end)
+ as_bad (_("--nops needs a numeric argument"));
+ }
+ break;
+
default:
return 0;
}
-V print assembler version number\n\
-Qy, -Qn ignored\n"));
#endif
+ fprintf (stream, _("\
+-nops=count when aligning, more than COUNT nops uses a branch\n"));
}
\f
/* Set ppc_cpu if it is not already set. */
char *dest = fragP->fr_literal + fragP->fr_fix;
fragP->fr_var = 4;
+
+ if (count > 4 * nop_limit && count < 0x2000000)
+ {
+ struct frag *rest;
+
+ /* Make a branch, then follow with nops. Insert another
+ frag to handle the nops. */
+ md_number_to_chars (dest, 0x48000000 + count, 4);
+ count -= 4;
+ if (count == 0)
+ return;
+
+ rest = xmalloc (SIZEOF_STRUCT_FRAG + 4);
+ memcpy (rest, fragP, SIZEOF_STRUCT_FRAG);
+ fragP->fr_next = rest;
+ fragP = rest;
+ rest->fr_address += rest->fr_fix + 4;
+ rest->fr_fix = 0;
+ /* If we leave the next frag as rs_align_code we'll come here
+ again, resulting in a bunch of branches rather than a
+ branch followed by nops. */
+ rest->fr_type = rs_align;
+ dest = rest->fr_literal;
+ }
+
md_number_to_chars (dest, 0x60000000, 4);
if ((ppc_cpu & PPC_OPCODE_POWER6) != 0