This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
check for invalid Xtensa instructions
- From: Bob Wilson <bwilson at tensilica dot com>
- To: binutils at sources dot redhat dot com
- Date: Fri, 12 Nov 2004 14:02:08 -0800
- Subject: check for invalid Xtensa instructions
- Organization: Tensilica, Inc.
I've committed this patch to check for Xtensa instructions that are invalid
because they contain more than one access to hardware interfaces that are
related (e.g., for hardware queues).
2004-11-12 Bob Wilson <bob.wilson@acm.org>
include/ChangeLog
* xtensa-isa-internal.h (xtensa_interface_internal): Add class_id.
* xtensa-isa.h (xtensa_interface_class_id): New prototype.
bfd/ChangeLog
* xtensa-isa.c (xtensa_interface_class_id): New.
gas/ChangeLog
* config/tc-xtensa.c (finish_vinsn): Clear pending instruction if
there is a conflict.
(check_t1_t2_reads_and_writes): Check for both reads and writes to
interfaces that are related as determined by xtensa_interface_class_id.
Index: include/xtensa-isa-internal.h
===================================================================
RCS file: /cvs/src/src/include/xtensa-isa-internal.h,v
retrieving revision 1.3
diff -u -p -r1.3 xtensa-isa-internal.h
--- include/xtensa-isa-internal.h 8 Oct 2004 00:22:12 -0000 1.3
+++ include/xtensa-isa-internal.h 12 Nov 2004 21:40:08 -0000
@@ -131,6 +131,7 @@ typedef struct xtensa_interface_internal
const char *name; /* Interface name. */
int num_bits; /* Width of the interface. */
uint32 flags; /* See XTENSA_INTERFACE_* flags. */
+ int class_id; /* Class of related interfaces. */
char inout; /* "i" or "o". */
} xtensa_interface_internal;
Index: include/xtensa-isa.h
===================================================================
RCS file: /cvs/src/src/include/xtensa-isa.h,v
retrieving revision 1.2
diff -u -p -r1.2 xtensa-isa.h
--- include/xtensa-isa.h 8 Oct 2004 00:22:12 -0000 1.2
+++ include/xtensa-isa.h 12 Nov 2004 21:40:08 -0000
@@ -755,6 +755,19 @@ xtensa_interface_inout (xtensa_isa isa,
extern int
xtensa_interface_has_side_effect (xtensa_isa isa, xtensa_interface intf);
+
+/* Some interfaces may be related such that accessing one interface
+ has side effects on a set of related interfaces. The interfaces
+ are partitioned into equivalence classes of related interfaces, and
+ each class is assigned a unique identifier number. This function
+ returns the class identifier for an interface, or XTENSA_UNDEFINED
+ on error. These identifiers can be compared to determine if two
+ interfaces are related; the specific values of the identifiers have
+ no particular meaning otherwise. */
+
+extern int
+xtensa_interface_class_id (xtensa_isa isa, xtensa_interface intf);
+
/* Functional Units. */
Index: bfd/xtensa-isa.c
===================================================================
RCS file: /cvs/src/src/bfd/xtensa-isa.c,v
retrieving revision 1.3
diff -u -p -r1.3 xtensa-isa.c
--- bfd/xtensa-isa.c 8 Oct 2004 00:22:10 -0000 1.3
+++ bfd/xtensa-isa.c 12 Nov 2004 21:40:08 -0000
@@ -1677,6 +1677,15 @@ xtensa_interface_has_side_effect (xtensa
return 0;
}
+
+int
+xtensa_interface_class_id (xtensa_isa isa, xtensa_interface intf)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
+ return intisa->interfaces[intf].class_id;
+}
+
/* Functional Units. */
Index: gas/config/tc-xtensa.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-xtensa.c,v
retrieving revision 1.17
diff -u -p -r1.17 tc-xtensa.c
--- gas/config/tc-xtensa.c 11 Nov 2004 19:05:41 -0000 1.17
+++ gas/config/tc-xtensa.c 12 Nov 2004 21:40:09 -0000
@@ -6013,7 +6013,7 @@ opcode_funcUnit_use_stage (void *data, x
solely whether the hardware is available to execute the given
instructions together. It also doesn't check if the tinsns
write the same state, or access the same tieports. That is
- checked by check_t1_t2_read_write. */
+ checked by check_t1_t2_reads_and_writes. */
static bfd_boolean
resources_conflict (vliw_insn *vinsn)
@@ -6069,7 +6069,10 @@ finish_vinsn (vliw_insn *vinsn)
int line;
if (find_vinsn_conflicts (vinsn))
- return;
+ {
+ xg_clear_vinsn (vinsn);
+ return;
+ }
/* First, find a format that works. */
if (vinsn->format == XTENSA_UNDEFINED)
@@ -6326,7 +6329,7 @@ find_vinsn_conflicts (vliw_insn *vinsn)
}
-/* Check how the result registers of t1 and t2 relate.
+/* Check how the state used by t1 and t2 relate.
Cases found are:
case A: t1 reads a register t2 writes (an antidependency within a bundle)
@@ -6336,7 +6339,7 @@ find_vinsn_conflicts (vliw_insn *vinsn)
bundle)
case D: t1 writes a state that t2 also writes
case E: t1 writes a tie queue that t2 also writes
- case F: two volatile queue writes
+ case F: two volatile queue accesses
*/
static char
@@ -6459,18 +6462,24 @@ check_t1_t2_reads_and_writes (TInsn *t1,
{
xtensa_interface t2_int
= xtensa_interfaceOperand_interface (isa, t2->opcode, j);
+ int t2_class = xtensa_interface_class_id (isa, t2_int);
+
t2_inout = xtensa_interface_inout (isa, j);
- if (xtensa_interface_has_side_effect (isa, t2_int) == 1
- && t2_inout != 'i')
+ if (xtensa_interface_has_side_effect (isa, t2_int) == 1)
t2_volatile = TRUE;
+
for (i = 0; i < t1_interfaces; i++)
{
xtensa_interface t1_int
= xtensa_interfaceOperand_interface (isa, t1->opcode, j);
+ int t1_class = xtensa_interface_class_id (isa, t2_int);
+
t1_inout = xtensa_interface_inout (isa, i);
- if (xtensa_interface_has_side_effect (isa, t1_int) == 1
- && t1_inout != 'i')
+ if (xtensa_interface_has_side_effect (isa, t1_int) == 1)
t1_volatile = TRUE;
+
+ if (t1_volatile && t2_volatile && (t1_class == t2_class))
+ return 'f';
if (t1_int != t2_int)
continue;
@@ -6491,9 +6500,6 @@ check_t1_t2_reads_and_writes (TInsn *t1,
return 'e';
}
}
-
- if (t1_volatile && t2_volatile)
- return 'f';
return conflict;
}