From 698544e152e041de8aaaaeea99f6f3c00ee99604 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 27 Apr 2012 18:03:13 +0000 Subject: 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. --- opcodes/ChangeLog | 5 +++++ opcodes/sparc-opc.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) (limited to 'opcodes') diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index a1e1fab..c20461b 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,5 +1,10 @@ 2012-04-27 David S. Miller + * sparc-opc.c (CBCOND): New define. + (CBCOND_XCC): Likewise. + (cbcond): New helper macro. + (sparc_opcodes): Add compare-and-branch instructions. + * sparc-dis.c (print_insn_sparc): Handle ')'. * sparc-opc.c (sparc_opcodes): Add crypto instructions. diff --git a/opcodes/sparc-opc.c b/opcodes/sparc-opc.c index 2ae6fd2..d83b49d 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 */ -- cgit v1.1