"Disp16" },
{ "OPERAND_TYPE_DISP32",
"Disp32" },
- { "OPERAND_TYPE_DISP32S",
- "Disp32S" },
{ "OPERAND_TYPE_DISP64",
"Disp64" },
{ "OPERAND_TYPE_INOUTPORTREG",
{ "OPERAND_TYPE_DISP16_32",
"Disp16|Disp32" },
{ "OPERAND_TYPE_ANYDISP",
- "Disp8|Disp16|Disp32|Disp32S|Disp64" },
+ "Disp8|Disp16|Disp32|Disp64" },
{ "OPERAND_TYPE_IMM16_32",
"Imm16|Imm32" },
{ "OPERAND_TYPE_IMM16_32S",
"Imm16|Imm32|Imm32S" },
{ "OPERAND_TYPE_IMM32_64",
"Imm32|Imm64" },
- { "OPERAND_TYPE_IMM32_32S_DISP32S",
- "Imm32|Imm32S|Disp32S" },
+ { "OPERAND_TYPE_IMM32_32S_DISP32",
+ "Imm32|Imm32S|Disp32" },
{ "OPERAND_TYPE_IMM64_DISP64",
"Imm64|Disp64" },
- { "OPERAND_TYPE_IMM32_32S_64_DISP32S",
- "Imm32|Imm32S|Imm64|Disp32S" },
- { "OPERAND_TYPE_IMM32_32S_64_DISP32S_64",
- "Imm32|Imm32S|Imm64|Disp32S|Disp64" },
+ { "OPERAND_TYPE_IMM32_32S_64_DISP32",
+ "Imm32|Imm32S|Imm64|Disp32" },
+ { "OPERAND_TYPE_IMM32_32S_64_DISP32_64",
+ "Imm32|Imm32S|Imm64|Disp32|Disp64" },
{ "OPERAND_TYPE_ANYIMM",
"Imm1|Imm8|Imm8S|Imm16|Imm32|Imm32S|Imm64" },
};
BITFIELD (Disp8),
BITFIELD (Disp16),
BITFIELD (Disp32),
- BITFIELD (Disp32S),
BITFIELD (Disp64),
BITFIELD (Byte),
BITFIELD (Word),
};
struct template {
- const struct template *next;
+ struct template *next;
const char *name;
const struct template_instance *instances;
const struct template_param *params;
};
-static const struct template *templates;
+static struct template *templates;
static int
compare (const void *x, const void *y)
fprintf (table, "%d },\n", modifier[i].value);
}
+/* Returns LOG2 of element size. */
static int
-adjust_broadcast_modifier (char **opnd)
+get_element_size (char **opnd, int lineno)
{
char *str, *next, *last, *op;
- int bcst_type = INT_MAX;
+ const char *full = opnd[0];
+ int elem_size = INT_MAX;
- /* Skip the immediate operand. */
- op = opnd[0];
- if (strcasecmp(op, "Imm8") == 0)
- op = opnd[1];
+ /* Find the memory operand. */
+ while (full != NULL && strstr(full, "BaseIndex") == NULL)
+ full = *++opnd;
+ if (full == NULL)
+ fail (_("%s: %d: no memory operand\n"), filename, lineno);
- op = xstrdup (op);
+ op = xstrdup (full);
last = op + strlen (op);
for (next = op; next && next < last; )
{
{
if (strcasecmp(str, "Byte") == 0)
{
- /* The smalest broadcast type, no need to check
+ /* The smallest element size, no need to check
further. */
- bcst_type = BYTE_BROADCAST;
+ elem_size = 0;
break;
}
else if (strcasecmp(str, "Word") == 0)
{
- if (bcst_type > WORD_BROADCAST)
- bcst_type = WORD_BROADCAST;
+ if (elem_size > 1)
+ elem_size = 1;
}
else if (strcasecmp(str, "Dword") == 0)
{
- if (bcst_type > DWORD_BROADCAST)
- bcst_type = DWORD_BROADCAST;
+ if (elem_size > 2)
+ elem_size = 2;
}
else if (strcasecmp(str, "Qword") == 0)
{
- if (bcst_type > QWORD_BROADCAST)
- bcst_type = QWORD_BROADCAST;
+ if (elem_size > 3)
+ elem_size = 3;
}
}
}
free (op);
- if (bcst_type == INT_MAX)
- fail (_("unknown broadcast operand: %s\n"), op);
+ if (elem_size == INT_MAX)
+ fail (_("%s: %d: unknown element size: %s\n"), filename, lineno, full);
- return bcst_type;
+ return elem_size;
}
static void
{
int val = 1;
if (strcasecmp(str, "Broadcast") == 0)
- val = adjust_broadcast_modifier (opnd);
+ val = get_element_size (opnd, lineno) + BYTE_BROADCAST;
+ else if (strcasecmp(str, "Disp8MemShift") == 0)
+ val = get_element_size (opnd, lineno);
set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
lineno);
if (!active_cpu_flags.bitfield.cpu64
&& !active_cpu_flags.bitfield.cpumpx)
set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
- if (!active_cpu_flags.bitfield.cpu64)
- set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
- if (!active_cpu_flags.bitfield.cpuno64)
- set_bitfield("Disp32S", types, 1, ARRAY_SIZE (types), lineno);
+ set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
}
}
output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
fail (_("%s:%d: %s: residual opcode (0x%0*llx) too large\n"),
filename, lineno, name, 2 * length, opcode);
- fprintf (table, " { \"%s\", 0x%0*llx%s, %s, %lu,\n",
- name, 2 * (int)length, opcode, end, extension_opcode, i);
+ fprintf (table, " { \"%s\", 0x%0*llx%s, %lu, %s,\n",
+ name, 2 * (int)length, opcode, end, i, extension_opcode);
process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
operand_types, lineno);
parse_template (char *buf, int lineno)
{
char sep, *end, *name;
- struct template *tmpl = xmalloc (sizeof (*tmpl));
+ struct template *tmpl;
struct template_instance *last_inst = NULL;
buf = remove_leading_whitespaces (buf + 1);
end = strchr (buf, ':');
if (end == NULL)
- fail ("%s: %d: missing ':'\n", filename, lineno);
+ {
+ struct template *prev = NULL;
+
+ end = strchr (buf, '>');
+ if (end == NULL)
+ fail ("%s: %d: missing ':' or '>'\n", filename, lineno);
+ if (*remove_leading_whitespaces (end + 1))
+ fail ("%s: %d: malformed template purge\n", filename, lineno);
+ *end = '\0';
+ remove_trailing_whitespaces (buf);
+ /* Don't bother freeing the various structures. */
+ for (tmpl = templates; tmpl != NULL; tmpl = (prev = tmpl)->next)
+ if (!strcmp (buf, tmpl->name))
+ break;
+ if (tmpl == NULL)
+ fail ("%s: %d: no template '%s'\n", filename, lineno, buf);
+ if (prev)
+ prev->next = tmpl->next;
+ else
+ templates = tmpl->next;
+ return;
+ }
*end++ = '\0';
remove_trailing_whitespaces (buf);
if (*buf == '\0')
fail ("%s: %d: missing template identifier\n", filename, lineno);
+ tmpl = xmalloc (sizeof (*tmpl));
tmpl->name = xstrdup (buf);
tmpl->params = NULL;
if (fgets (buf, sizeof (buf), fp) == NULL)
break;
- lineno++;
-
p = remove_leading_whitespaces (buf);
- /* Skip comments. */
- str = strstr (p, "//");
- if (str != NULL)
- str[0] = '\0';
+ for ( ; ; )
+ {
+ lineno++;
- /* Remove trailing white spaces. */
- remove_trailing_whitespaces (p);
+ /* Skip comments. */
+ str = strstr (p, "//");
+ if (str != NULL)
+ {
+ str[0] = '\0';
+ remove_trailing_whitespaces (p);
+ break;
+ }
+
+ /* Look for line continuation character. */
+ remove_trailing_whitespaces (p);
+ j = strlen (buf);
+ if (!j || buf[j - 1] != '+')
+ break;
+ if (j >= sizeof (buf) - 1)
+ fail (_("%s: %d: (continued) line too long\n"), filename, lineno);
+
+ if (fgets (buf + j - 1, sizeof (buf) - j + 1, fp) == NULL)
+ {
+ fprintf (stderr, "%s: Line continuation on last line?\n",
+ filename);
+ break;
+ }
+ }
switch (p[0])
{