{"ds.b", s_space, 1},
{"ds.d", s_space, 8},
{"ds.l", s_space, 4},
- {"ds.p", s_space, 12},
+ {"ds.p", s_space, 'p'},
{"ds.s", s_space, 4},
{"ds.w", s_space, 2},
- {"ds.x", s_space, 12},
+ {"ds.x", s_space, 'x'},
{"debug", s_ignore, 0},
#ifdef S_SET_DESC
{"desc", s_desc, 0},
md_flush_pending_output ();
#endif
+ switch (mult)
+ {
+ case 'x':
+#ifdef X_PRECISION
+# ifndef P_PRECISION
+# define P_PRECISION X_PRECISION
+# define P_PRECISION_PAD X_PRECISION_PAD
+# endif
+ mult = (X_PRECISION + X_PRECISION_PAD) * sizeof (LITTLENUM_TYPE);
+ if (!mult)
+#endif
+ mult = 12;
+ break;
+
+ case 'p':
+#ifdef P_PRECISION
+ mult = (P_PRECISION + P_PRECISION_PAD) * sizeof (LITTLENUM_TYPE);
+ if (!mult)
+#endif
+ mult = 12;
+ break;
+ }
+
#ifdef md_cons_align
md_cons_align (1);
#endif
*p = val.X_add_number;
}
-/* This is like s_space, but the value is a floating point number with
- the given precision. This is for the MRI dcb.s pseudo-op and
- friends. */
+/* Obtain the size of a floating point number, given a type. */
-void
-s_float_space (int float_type)
+static int
+float_length (int float_type, int *pad_p)
{
- offsetT count;
- int flen;
- char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
- char *stop = NULL;
- char stopc = 0;
+ int length, pad = 0;
-#ifdef md_cons_align
- md_cons_align (1);
-#endif
+ switch (float_type)
+ {
+ case 'b':
+ case 'B':
+ case 'h':
+ case 'H':
+ length = 2;
+ break;
- if (flag_mri)
- stop = mri_comment_field (&stopc);
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ length = 4;
+ break;
- count = get_absolute_expression ();
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ length = 8;
+ break;
- SKIP_WHITESPACE ();
- if (*input_line_pointer != ',')
- {
- as_bad (_("missing value"));
- ignore_rest_of_line ();
- if (flag_mri)
- mri_comment_end (stop, stopc);
- return;
+ case 'x':
+ case 'X':
+#ifdef X_PRECISION
+ length = X_PRECISION * sizeof (LITTLENUM_TYPE);
+ pad = X_PRECISION_PAD * sizeof (LITTLENUM_TYPE);
+ if (!length)
+#endif
+ length = 12;
+ break;
+
+ case 'p':
+ case 'P':
+#ifdef P_PRECISION
+ length = P_PRECISION * sizeof (LITTLENUM_TYPE);
+ pad = P_PRECISION_PAD * sizeof (LITTLENUM_TYPE);
+ if (!length)
+#endif
+ length = 12;
+ break;
+
+ default:
+ as_bad (_("unknown floating type '%c'"), float_type);
+ length = -1;
+ break;
}
- ++input_line_pointer;
+ if (pad_p)
+ *pad_p = pad;
+
+ return length;
+}
+
+static int
+parse_one_float (int float_type, char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT])
+{
+ int length;
SKIP_WHITESPACE ();
/* Skip any 0{letter} that may be present. Don't even check if the
- * letter is legal. */
+ letter is legal. Someone may invent a "z" format and this routine
+ has no use for such information. Lusers beware: you get
+ diagnostics if your input is ill-conditioned. */
if (input_line_pointer[0] == '0'
&& ISALPHA (input_line_pointer[1]))
input_line_pointer += 2;
with the exact digits specified. */
if (input_line_pointer[0] == ':')
{
- flen = hex_float (float_type, temp);
- if (flen < 0)
+ ++input_line_pointer;
+ length = hex_float (float_type, temp);
+ if (length < 0)
{
ignore_rest_of_line ();
- if (flag_mri)
- mri_comment_end (stop, stopc);
- return;
+ return length;
}
}
else
{
const char *err;
- err = md_atof (float_type, temp, &flen);
- know (flen <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
- know (err != NULL || flen > 0);
+ err = md_atof (float_type, temp, &length);
+ know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
+ know (err != NULL || length > 0);
if (err)
{
as_bad (_("bad floating literal: %s"), err);
ignore_rest_of_line ();
- if (flag_mri)
- mri_comment_end (stop, stopc);
- return;
+ return -1;
}
}
+ return length;
+}
+
+/* This is like s_space, but the value is a floating point number with
+ the given precision. This is for the MRI dcb.s pseudo-op and
+ friends. */
+
+void
+s_float_space (int float_type)
+{
+ offsetT count;
+ int flen;
+ char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
+ char *stop = NULL;
+ char stopc = 0;
+
+#ifdef md_cons_align
+ md_cons_align (1);
+#endif
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ count = get_absolute_expression ();
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ int pad;
+
+ flen = float_length (float_type, &pad);
+ if (flen >= 0)
+ memset (temp, 0, flen += pad);
+ }
+ else
+ {
+ ++input_line_pointer;
+
+ flen = parse_one_float (float_type, temp);
+ }
+
+ if (flen < 0)
+ {
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+ return;
+ }
+
while (--count >= 0)
{
char *p;
use = get & unmask;
if ((get & mask) != 0 && (-get & mask) != 0)
{
+ char get_buf[128];
+ char use_buf[128];
+
+ /* These buffers help to ease the translation of the warning message. */
+ sprintf_vma (get_buf, get);
+ sprintf_vma (use_buf, use);
/* Leading bits contain both 0s & 1s. */
- as_warn (_("value 0x%" BFD_VMA_FMT "x truncated to 0x%" BFD_VMA_FMT "x"),
- get, use);
+ as_warn (_("value 0x%s truncated to 0x%s"), get_buf, use_buf);
}
/* Put bytes in right order. */
md_number_to_chars (p, use, (int) nbytes);
static int
hex_float (int float_type, char *bytes)
{
- int length;
+ int pad, length = float_length (float_type, &pad);
int i;
- switch (float_type)
- {
- case 'f':
- case 'F':
- case 's':
- case 'S':
- length = 4;
- break;
-
- case 'd':
- case 'D':
- case 'r':
- case 'R':
- length = 8;
- break;
-
- case 'x':
- case 'X':
- length = 12;
- break;
-
- case 'p':
- case 'P':
- length = 12;
- break;
-
- default:
- as_bad (_("unknown floating type type '%c'"), float_type);
- return -1;
- }
+ if (length < 0)
+ return length;
/* It would be nice if we could go through expression to parse the
hex constant, but if we get a bignum it's a pain to sort it into
memset (bytes, 0, length - i);
}
- return length;
+ memset (bytes + length, 0, pad);
+
+ return length + pad;
}
/* float_cons()
{
char *p;
int length; /* Number of chars in an object. */
- const char *err; /* Error from scanning floating literal. */
char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
if (is_it_end_of_statement ())
do
{
- /* input_line_pointer->1st char of a flonum (we hope!). */
- SKIP_WHITESPACE ();
-
- /* Skip any 0{letter} that may be present. Don't even check if the
- letter is legal. Someone may invent a "z" format and this routine
- has no use for such information. Lusers beware: you get
- diagnostics if your input is ill-conditioned. */
- if (input_line_pointer[0] == '0'
- && ISALPHA (input_line_pointer[1]))
- input_line_pointer += 2;
-
- /* Accept :xxxx, where the x's are hex digits, for a floating
- point with the exact digits specified. */
- if (input_line_pointer[0] == ':')
- {
- ++input_line_pointer;
- length = hex_float (float_type, temp);
- if (length < 0)
- {
- ignore_rest_of_line ();
- return;
- }
- }
- else
- {
- err = md_atof (float_type, temp, &length);
- know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
- know (err != NULL || length > 0);
- if (err)
- {
- as_bad (_("bad floating literal: %s"), err);
- ignore_rest_of_line ();
- return;
- }
- }
+ length = parse_one_float (float_type, temp);
+ if (length < 0)
+ return;
if (!need_pass_2)
{