summaryrefslogtreecommitdiff
path: root/opcodes/sparc-opc.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@redhat.com>2012-04-27 18:03:13 +0000
committerDavid S. Miller <davem@redhat.com>2012-04-27 18:03:13 +0000
commit698544e152e041de8aaaaeea99f6f3c00ee99604 (patch)
tree264045c30492ca6144e246820391c0b5cf651a1d /opcodes/sparc-opc.c
parent6cda13266f4d767456ccd5ee9f4c8539b463fc0e (diff)
downloadbinutils-gdb-698544e152e041de8aaaaeea99f6f3c00ee99604.tar.gz
Add support for sparc compare-and-branch instructions.
opcodes/ * sparc-opc.c (CBCOND): New define. (CBCOND_XCC): Likewise. (cbcond): New helper macro. (sparc_opcodes): Add compare-and-branch instructions. gas/ * config/tc-sparc.c (sparc_arch_table): Add HWCAP_CBCOND to sparc4, v8pluse, v8plusv, v9e, and v9v. (sparc_ip): Handle R_SPARC_5 of immediate constants inline in order to accomodate cbcond which otherwise would require two relocations to be handled in a single instruction.. gas/testsuite/ * gas/sparc/cbcond.s: New file. * gas/sparc/cbcond.d: New file. * gas/sparc/sparc.exp: Run cbcond test.
Diffstat (limited to 'opcodes/sparc-opc.c')
-rw-r--r--opcodes/sparc-opc.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/opcodes/sparc-opc.c b/opcodes/sparc-opc.c
index 2ae6fd2bad4..d83b49d3f02 100644
--- a/opcodes/sparc-opc.c
+++ b/opcodes/sparc-opc.c
@@ -104,6 +104,9 @@ sparc_opcode_lookup_arch (const char *name)
/* Branch condition field. */
#define COND(x) (((x) & 0xf) << 25)
+/* Compare And Branch condition field. */
+#define CBCOND(x) (((x) & 0x1f) << 25)
+
/* v9: Move (MOVcc and FMOVcc) condition field. */
#define MCOND(x,i_or_f) ((((i_or_f) & 1) << 18) | (((x) >> 11) & (0xf << 14))) /* v9 */
@@ -154,6 +157,7 @@ sparc_opcode_lookup_arch (const char *name)
#define ICC (0) /* v9 */
#define XCC (1 << 12) /* v9 */
+#define CBCOND_XCC (1 << 21)
#define FCC(x) (((x) & 0x3) << 11) /* v9 */
#define FBFCC(x) (((x) & 0x3) << 20) /* v9 */
@@ -1191,6 +1195,32 @@ cond ("bz", "tz", CONDZ, F_CONDBR|F_ALIAS), /* for e */
/* v9 */ condr("brlez", 0x2, F_CONDBR),
/* v9 */ condr("brgz", 0x6, F_CONDBR),
+#define cbcond(cop, cmask) \
+ { "cw" cop, F2(0, 3)|CBCOND(cmask)|F3I(0),F2(~0,~3)|CBCOND(~(cmask))|F3I(~0)|CBCOND_XCC, \
+ "1,2,=", F_CONDBR, HWCAP_CBCOND, v9}, \
+ { "cw" cop, F2(0, 3)|CBCOND(cmask)|F3I(1),F2(~0,~3)|CBCOND(~(cmask))|F3I(~1)|CBCOND_XCC, \
+ "1,X,=", F_CONDBR, HWCAP_CBCOND, v9}, \
+ { "cx" cop, F2(0, 3)|CBCOND(cmask)|F3I(0)|CBCOND_XCC,F2(~0,~3)|CBCOND(~(cmask))|F3I(~0), \
+ "1,2,=", F_CONDBR, HWCAP_CBCOND, v9}, \
+ { "cx" cop, F2(0, 3)|CBCOND(cmask)|F3I(1)|CBCOND_XCC,F2(~0,~3)|CBCOND(~(cmask))|F3I(~1), \
+ "1,X,=", F_CONDBR, HWCAP_CBCOND, v9},
+
+cbcond("be", 0x09)
+cbcond("ble", 0x0a)
+cbcond("bl", 0x0b)
+cbcond("bleu", 0x0c)
+cbcond("bcs", 0x0d)
+cbcond("bneg", 0x0e)
+cbcond("bvs", 0x0f)
+cbcond("bne", 0x19)
+cbcond("bg", 0x1a)
+cbcond("bge", 0x1b)
+cbcond("bgu", 0x1c)
+cbcond("bcc", 0x1d)
+cbcond("bpos", 0x1e)
+cbcond("bvc", 0x1f)
+
+#undef cbcond
#undef condr /* v9 */
#undef brr /* v9 */