2008-01-09 H.J. Lu <hongjiu.lu@intel.com>

* config/tc-i386.c (match_template): Check register size
	only when size of operands can be encoded the canonical way.
This commit is contained in:
H.J. Lu
2008-01-09 16:55:14 +00:00
parent 0aea4bf354
commit 45664ddbb0
2 changed files with 32 additions and 29 deletions

View File

@ -1,3 +1,8 @@
2008-01-09 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (match_template): Check register size
only when size of operands can be encoded the canonical way.
2008-01-08 H.J. Lu <hongjiu.lu@intel.com> 2008-01-08 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (i386_operand): Renamed to ... * config/tc-i386.c (i386_operand): Renamed to ...

View File

@ -2967,6 +2967,7 @@ match_template (void)
int addr_prefix_disp; int addr_prefix_disp;
unsigned int j; unsigned int j;
unsigned int found_cpu_match; unsigned int found_cpu_match;
unsigned int check_register;
#if MAX_OPERANDS != 4 #if MAX_OPERANDS != 4
# error "MAX_OPERANDS must be 4." # error "MAX_OPERANDS must be 4."
@ -3110,6 +3111,9 @@ match_template (void)
} }
} }
/* We check register size only if size of operands can be
encoded the canonical way. */
check_register = t->opcode_modifier.w;
overlap0 = operand_type_and (i.types[0], operand_types[0]); overlap0 = operand_type_and (i.types[0], operand_types[0]);
switch (t->operands) switch (t->operands)
{ {
@ -3132,19 +3136,8 @@ match_template (void)
overlap1 = operand_type_and (i.types[1], operand_types[1]); overlap1 = operand_type_and (i.types[1], operand_types[1]);
if (!operand_type_match (overlap0, i.types[0]) if (!operand_type_match (overlap0, i.types[0])
|| !operand_type_match (overlap1, i.types[1]) || !operand_type_match (overlap1, i.types[1])
/* monitor in SSE3 is a very special case. The first || (check_register
register and the second register may have different && !operand_type_register_match (overlap0, i.types[0],
sizes. The same applies to crc32 in SSE4.2. It is
also true for invlpga, vmload, vmrun and vmsave in
SVME. */
|| !((t->base_opcode == 0x0f01
&& (t->extension_opcode == 0xc8
|| t->extension_opcode == 0xd8
|| t->extension_opcode == 0xda
|| t->extension_opcode == 0xdb
|| t->extension_opcode == 0xdf))
|| t->base_opcode == 0xf20f38f1
|| operand_type_register_match (overlap0, i.types[0],
operand_types[0], operand_types[0],
overlap1, i.types[1], overlap1, i.types[1],
operand_types[1]))) operand_types[1])))
@ -3158,10 +3151,13 @@ match_template (void)
overlap1 = operand_type_and (i.types[1], operand_types[0]); overlap1 = operand_type_and (i.types[1], operand_types[0]);
if (!operand_type_match (overlap0, i.types[0]) if (!operand_type_match (overlap0, i.types[0])
|| !operand_type_match (overlap1, i.types[1]) || !operand_type_match (overlap1, i.types[1])
|| !operand_type_register_match (overlap0, i.types[0], || (check_register
&& !operand_type_register_match (overlap0,
i.types[0],
operand_types[1], operand_types[1],
overlap1, i.types[1], overlap1,
operand_types[0])) i.types[1],
operand_types[0])))
{ {
/* Does not match either direction. */ /* Does not match either direction. */
continue; continue;
@ -3195,12 +3191,13 @@ match_template (void)
{ {
case 4: case 4:
if (!operand_type_match (overlap3, i.types[3]) if (!operand_type_match (overlap3, i.types[3])
|| !operand_type_register_match (overlap2, || (check_register
&& !operand_type_register_match (overlap2,
i.types[2], i.types[2],
operand_types[2], operand_types[2],
overlap3, overlap3,
i.types[3], i.types[3],
operand_types[3])) operand_types[3])))
continue; continue;
case 3: case 3:
/* Here we make use of the fact that there are no /* Here we make use of the fact that there are no
@ -3208,12 +3205,13 @@ match_template (void)
operand instructions only need to be checked for operand instructions only need to be checked for
register consistency between operands 2 and 3. */ register consistency between operands 2 and 3. */
if (!operand_type_match (overlap2, i.types[2]) if (!operand_type_match (overlap2, i.types[2])
|| !operand_type_register_match (overlap1, || (check_register
&& !operand_type_register_match (overlap1,
i.types[1], i.types[1],
operand_types[1], operand_types[1],
overlap2, overlap2,
i.types[2], i.types[2],
operand_types[2])) operand_types[2])))
continue; continue;
break; break;
} }