if (idesc->operands[2] == IA64_OPND_SOF
|| idesc->operands[1] == IA64_OPND_SOF)
{
- /* map alloc r1=ar.pfs,i,l,o,r to alloc r1=ar.pfs,(i+l+o),(i+l),r */
+ /* Map alloc r1=ar.pfs,i,l,o,r to alloc r1=ar.pfs,(i+l+o),(i+l),r.
+ Note, however, that due to that mapping operand numbers in error
+ messages for any of the constant operands will not be correct. */
know (strcmp (idesc->name, "alloc") == 0);
- i = (CURR_SLOT.opnd[1].X_op == O_register
- && CURR_SLOT.opnd[1].X_add_number == REG_AR + AR_PFS) ? 2 : 1;
- if (num_operands == i + 3 /* first_arg not included in this count! */
- && CURR_SLOT.opnd[i].X_op == O_constant
- && CURR_SLOT.opnd[i + 1].X_op == O_constant
- && CURR_SLOT.opnd[i + 2].X_op == O_constant
- && CURR_SLOT.opnd[i + 3].X_op == O_constant)
- {
- sof = set_regstack (CURR_SLOT.opnd[i].X_add_number,
- CURR_SLOT.opnd[i + 1].X_add_number,
- CURR_SLOT.opnd[i + 2].X_add_number,
- CURR_SLOT.opnd[i + 3].X_add_number);
-
- /* now we can parse the first arg: */
- saved_input_pointer = input_line_pointer;
- input_line_pointer = first_arg;
- sep = parse_operand (CURR_SLOT.opnd + 0, '=');
- if (sep != '=')
- --num_outputs; /* force error */
- input_line_pointer = saved_input_pointer;
-
- CURR_SLOT.opnd[i].X_add_number = sof;
- CURR_SLOT.opnd[i + 1].X_add_number
- = sof - CURR_SLOT.opnd[i + 2].X_add_number;
- CURR_SLOT.opnd[i + 2] = CURR_SLOT.opnd[i + 3];
- }
+ /* The first operand hasn't been parsed/initialized, yet (but
+ num_operands intentionally doesn't account for that). */
+ i = num_operands > 4 ? 2 : 1;
+#define FORCE_CONST(n) (CURR_SLOT.opnd[n].X_op == O_constant \
+ ? CURR_SLOT.opnd[n].X_add_number \
+ : 0)
+ sof = set_regstack (FORCE_CONST(i),
+ FORCE_CONST(i + 1),
+ FORCE_CONST(i + 2),
+ FORCE_CONST(i + 3));
+#undef FORCE_CONST
+
+ /* now we can parse the first arg: */
+ saved_input_pointer = input_line_pointer;
+ input_line_pointer = first_arg;
+ sep = parse_operand (CURR_SLOT.opnd + 0, '=');
+ if (sep != '=')
+ --num_outputs; /* force error */
+ input_line_pointer = saved_input_pointer;
+
+ CURR_SLOT.opnd[i].X_add_number = sof;
+ if (CURR_SLOT.opnd[i + 1].X_op == O_constant
+ && CURR_SLOT.opnd[i + 2].X_op == O_constant)
+ CURR_SLOT.opnd[i + 1].X_add_number
+ = sof - CURR_SLOT.opnd[i + 2].X_add_number;
+ else
+ CURR_SLOT.opnd[i + 1].X_op = O_illegal;
+ CURR_SLOT.opnd[i + 2] = CURR_SLOT.opnd[i + 3];
}
highest_unmatched_operand = -4;
--- /dev/null
+# Currently in the error messages the operand numbers for the constants
+# aren't correct, which is why the patterns only check for ranges.
+.*: Assembler messages:
+.*:7: Error: Operand [345] of .alloc. should be .*
+.*:8: Error: Operand [345] of .alloc. should be .*
+.*:9: Error: Operand [345] of .alloc. should be .*
+.*:10: Error: Operand [56] of .alloc. should be .*
+.*:11: Error: Operand [234] of .alloc. should be .*
+.*:12: Error: Operand [234] of .alloc. should be .*
+.*:13: Error: Operand [234] of .alloc. should be .*
+.*:14: Error: Operand [45] of .alloc. should be .*
--- /dev/null
+// Make sure error messages on 'alloc' don't needlessly refer to operand 1
+// (which gets parsed late) when only one of the other operands is wrong.
+
+ .text
+
+alloc:
+ alloc r2 = ar.pfs, x, 0, 0, 0
+ alloc r2 = ar.pfs, 0, x, 0, 0
+ alloc r2 = ar.pfs, 0, 0, x, 0
+ alloc r2 = ar.pfs, 0, 0, 0, x
+ alloc r3 = x, 0, 0, 0
+ alloc r3 = 0, x, 0, 0
+ alloc r3 = 0, 0, x, 0
+ alloc r3 = 0, 0, 0, x