Add support for sparc compare-and-branch instructions.
authorDavid S. Miller <davem@redhat.com>
Fri, 27 Apr 2012 18:03:13 +0000 (18:03 +0000)
committerDavid S. Miller <davem@redhat.com>
Fri, 27 Apr 2012 18:03:13 +0000 (18:03 +0000)
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.

gas/ChangeLog
gas/config/tc-sparc.c
gas/testsuite/ChangeLog
gas/testsuite/gas/sparc/cbcond.d [new file with mode: 0644]
gas/testsuite/gas/sparc/cbcond.s [new file with mode: 0644]
gas/testsuite/gas/sparc/sparc.exp
opcodes/ChangeLog
opcodes/sparc-opc.c

index ff8b2ff1afbc6c390081b5b02deda23493740e6a..ca23ecb32a295c42cd494262ecd38e1b8d439ddc 100644 (file)
@@ -1,5 +1,11 @@
 2012-04-27  David S. Miller  <davem@davemloft.net>
 
+       * 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..
+
        * config/tc-sparc.c (sparc_ip): Likewise.  Accept instruction
        names containing "_".
        (sparc_arch_table): Add sparc4, v8pluse, and v9e.  Add crypto
index f2f0ae8a92bae8f951306fc6d408ed198643a092..3e95357a7923fe3b5229bc1cc614b6276fb04f91 100644 (file)
@@ -245,7 +245,7 @@ static struct sparc_arch {
   { "sparcfmaf", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF },
   { "sparcima", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF|HWCAP_IMA },
   { "sparcvis3", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC },
-  { "sparc4", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_RANDOM|HWCAP_TRANS|HWCAP_FJFMAU|HWCAP_AES|HWCAP_DES|HWCAP_KASUMI|HWCAP_CAMELLIA|HWCAP_MD5|HWCAP_SHA1|HWCAP_SHA256|HWCAP_SHA512|HWCAP_MPMUL|HWCAP_MONT|HWCAP_CRC32C },
+  { "sparc4", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_RANDOM|HWCAP_TRANS|HWCAP_FJFMAU|HWCAP_AES|HWCAP_DES|HWCAP_KASUMI|HWCAP_CAMELLIA|HWCAP_MD5|HWCAP_SHA1|HWCAP_SHA256|HWCAP_SHA512|HWCAP_MPMUL|HWCAP_MONT|HWCAP_CRC32C|HWCAP_CBCOND },
   { "sparcvis3r", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_RANDOM|HWCAP_TRANS|HWCAP_FJFMAU },
   { "sparclet", "sparclet", sparclet, 32, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD },
   { "sparclite", "sparclite", sparclite, 32, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD },
@@ -255,15 +255,15 @@ static struct sparc_arch {
   { "v8plusb", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2 },
   { "v8plusc", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT },
   { "v8plusd", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC },
-  { "v8pluse", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_AES|HWCAP_DES|HWCAP_KASUMI|HWCAP_CAMELLIA|HWCAP_MD5|HWCAP_SHA1|HWCAP_SHA256|HWCAP_SHA512|HWCAP_MPMUL|HWCAP_MONT|HWCAP_CRC32C },
-  { "v8plusv", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_RANDOM|HWCAP_TRANS|HWCAP_FJFMAU|HWCAP_IMA|HWCAP_ASI_CACHE_SPARING|HWCAP_AES|HWCAP_DES|HWCAP_KASUMI|HWCAP_CAMELLIA|HWCAP_MD5|HWCAP_SHA1|HWCAP_SHA256|HWCAP_SHA512|HWCAP_MPMUL|HWCAP_MONT|HWCAP_CRC32C },
+  { "v8pluse", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_AES|HWCAP_DES|HWCAP_KASUMI|HWCAP_CAMELLIA|HWCAP_MD5|HWCAP_SHA1|HWCAP_SHA256|HWCAP_SHA512|HWCAP_MPMUL|HWCAP_MONT|HWCAP_CRC32C|HWCAP_CBCOND },
+  { "v8plusv", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_RANDOM|HWCAP_TRANS|HWCAP_FJFMAU|HWCAP_IMA|HWCAP_ASI_CACHE_SPARING|HWCAP_AES|HWCAP_DES|HWCAP_KASUMI|HWCAP_CAMELLIA|HWCAP_MD5|HWCAP_SHA1|HWCAP_SHA256|HWCAP_SHA512|HWCAP_MPMUL|HWCAP_MONT|HWCAP_CRC32C|HWCAP_CBCOND },
   { "v9", "v9", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC },
   { "v9a", "v9a", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS },
   { "v9b", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2 },
   { "v9c", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT },
   { "v9d", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC },
-  { "v9e", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_AES|HWCAP_DES|HWCAP_KASUMI|HWCAP_CAMELLIA|HWCAP_MD5|HWCAP_SHA1|HWCAP_SHA256|HWCAP_SHA512|HWCAP_MPMUL|HWCAP_MONT|HWCAP_CRC32C },
-  { "v9v", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_RANDOM|HWCAP_TRANS|HWCAP_FJFMAU|HWCAP_IMA|HWCAP_ASI_CACHE_SPARING|HWCAP_AES|HWCAP_DES|HWCAP_KASUMI|HWCAP_CAMELLIA|HWCAP_MD5|HWCAP_SHA1|HWCAP_SHA256|HWCAP_SHA512|HWCAP_MPMUL|HWCAP_MONT|HWCAP_CRC32C },
+  { "v9e", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_AES|HWCAP_DES|HWCAP_KASUMI|HWCAP_CAMELLIA|HWCAP_MD5|HWCAP_SHA1|HWCAP_SHA256|HWCAP_SHA512|HWCAP_MPMUL|HWCAP_MONT|HWCAP_CRC32C|HWCAP_CBCOND },
+  { "v9v", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_RANDOM|HWCAP_TRANS|HWCAP_FJFMAU|HWCAP_IMA|HWCAP_ASI_CACHE_SPARING|HWCAP_AES|HWCAP_DES|HWCAP_KASUMI|HWCAP_CAMELLIA|HWCAP_MD5|HWCAP_SHA1|HWCAP_SHA256|HWCAP_SHA512|HWCAP_MPMUL|HWCAP_MONT|HWCAP_CRC32C|HWCAP_CBCOND },
   /* This exists to allow configure.in/Makefile.in to pass one
      value to specify both the default machine and default word size.  */
   { "v9-64", "v9", v9, 64, 0, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC },
@@ -2703,6 +2703,26 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn)
                     all the various cases (e.g. in md_apply_fix and
                     bfd_install_relocation) so duplicating all that code
                     here isn't right.  */
+
+                 /* This is a special case to handle cbcond instructions
+                    properly, which can need two relocations.  The first
+                    one is for the 5-bit immediate field and the latter
+                    is going to be for the WDISP10 branch part.  We
+                    handle the R_SPARC_5 immediate directly here so that
+                    we don't need to add support for multiple relocations
+                    in one instruction just yet.  */
+                 if (the_insn.reloc == BFD_RELOC_SPARC_5)
+                   {
+                     valueT val = the_insn.exp.X_add_number;
+
+                     if (! in_bitfield_range (val, 0x1f))
+                       {
+                         error_message = _(": Immediate value in cbcond is out of range.");
+                         goto error;
+                       }
+                     opcode |= val & 0x1f;
+                     the_insn.reloc = BFD_RELOC_NONE;
+                   }
                }
 
              continue;
index a3b3a326ff11dcf06e34d7f08c5976736c7b7fad..478a4dee98ac8b8948427b06d4e0a3e47636b099 100644 (file)
@@ -1,5 +1,9 @@
 2012-04-27  David S. Miller  <davem@davemloft.net>
 
+       * gas/sparc/cbcond.s: New file.
+       * gas/sparc/cbcond.d: New file.
+       * gas/sparc/sparc.exp: Run cbcond test.
+
        * gas/sparc/crypto.s: New file.
        * gas/sparc/crypto.d: New file.
        * gas/sparc/sparc.exp: Run crypto test.
diff --git a/gas/testsuite/gas/sparc/cbcond.d b/gas/testsuite/gas/sparc/cbcond.d
new file mode 100644 (file)
index 0000000..d094045
--- /dev/null
@@ -0,0 +1,66 @@
+#as: -Av9v
+#objdump: -dr
+#name: sparc CBCOND
+
+.*: +file format .*sparc.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+   0:  12 c2 47 0a     cwbe  %o1, %o2, 0xe0
+   4:  12 c2 66 e2     cwbe  %o1, 2, 0xe0
+   8:  12 e2 86 cb     cxbe  %o2, %o3, 0xe0
+   c:  12 e2 a6 a3     cxbe  %o2, 3, 0xe0
+  10:  14 c2 c6 8c     cwble  %o3, %o4, 0xe0
+  14:  14 c2 e6 64     cwble  %o3, 4, 0xe0
+  18:  14 e3 06 4d     cxble  %o4, %o5, 0xe0
+  1c:  14 e3 26 25     cxble  %o4, 5, 0xe0
+  20:  16 c3 46 10     cwbl  %o5, %l0, 0xe0
+  24:  16 c3 65 e6     cwbl  %o5, 6, 0xe0
+  28:  16 e4 05 d1     cxbl  %l0, %l1, 0xe0
+  2c:  16 e4 25 a7     cxbl  %l0, 7, 0xe0
+  30:  18 c4 45 92     cwbleu  %l1, %l2, 0xe0
+  34:  18 c4 65 68     cwbleu  %l1, 8, 0xe0
+  38:  18 e4 85 53     cxbleu  %l2, %l3, 0xe0
+  3c:  18 e4 a5 29     cxbleu  %l2, 9, 0xe0
+  40:  1a c4 c5 14     cwbcs  %l3, %l4, 0xe0
+  44:  1a c4 e4 ea     cwbcs  %l3, 0xa, 0xe0
+  48:  1a e5 04 d5     cxbcs  %l4, %l5, 0xe0
+  4c:  1a e5 24 ab     cxbcs  %l4, 0xb, 0xe0
+  50:  1c c5 44 96     cwbneg  %l5, %l6, 0xe0
+  54:  1c c5 64 6c     cwbneg  %l5, 0xc, 0xe0
+  58:  1c e5 84 57     cxbneg  %l6, %l7, 0xe0
+  5c:  1c e5 a4 2d     cxbneg  %l6, 0xd, 0xe0
+  60:  1e c5 c4 18     cwbvs  %l7, %i0, 0xe0
+  64:  1e c5 e3 ee     cwbvs  %l7, 0xe, 0xe0
+  68:  1e e6 03 d9     cxbvs  %i0, %i1, 0xe0
+  6c:  1e e6 23 af     cxbvs  %i0, 0xf, 0xe0
+  70:  32 c6 43 9a     cwbne  %i1, %i2, 0xe0
+  74:  32 c6 63 70     cwbne  %i1, 0x10, 0xe0
+  78:  32 e6 83 5b     cxbne  %i2, %i3, 0xe0
+  7c:  32 e6 a3 31     cxbne  %i2, 0x11, 0xe0
+  80:  34 c6 c3 1c     cwbg  %i3, %i4, 0xe0
+  84:  34 c6 e2 f2     cwbg  %i3, 0x12, 0xe0
+  88:  34 e7 02 dd     cxbg  %i4, %i5, 0xe0
+  8c:  34 e7 22 b3     cxbg  %i4, 0x13, 0xe0
+  90:  36 c7 42 88     cwbge  %i5, %o0, 0xe0
+  94:  36 c7 62 74     cwbge  %i5, 0x14, 0xe0
+  98:  36 e2 02 49     cxbge  %o0, %o1, 0xe0
+  9c:  36 e2 22 35     cxbge  %o0, 0x15, 0xe0
+  a0:  38 c2 42 0a     cwbgu  %o1, %o2, 0xe0
+  a4:  38 c2 61 f6     cwbgu  %o1, 0x16, 0xe0
+  a8:  38 e2 81 cb     cxbgu  %o2, %o3, 0xe0
+  ac:  38 e2 a1 b6     cxbgu  %o2, 0x16, 0xe0
+  b0:  3a c2 c1 8c     cwbcc  %o3, %o4, 0xe0
+  b4:  3a c2 e1 77     cwbcc  %o3, 0x17, 0xe0
+  b8:  3a e3 01 4d     cxbcc  %o4, %o5, 0xe0
+  bc:  3a e3 21 38     cxbcc  %o4, 0x18, 0xe0
+  c0:  3c c3 41 10     cwbpos  %o5, %l0, 0xe0
+  c4:  3c c3 60 f9     cwbpos  %o5, 0x19, 0xe0
+  c8:  3c e4 00 d1     cxbpos  %l0, %l1, 0xe0
+  cc:  3c e4 20 b9     cxbpos  %l0, 0x19, 0xe0
+  d0:  3e c4 40 92     cwbvc  %l1, %l2, 0xe0
+  d4:  3e c4 60 7a     cwbvc  %l1, 0x1a, 0xe0
+  d8:  3e e4 80 53     cxbvc  %l2, %l3, 0xe0
+  dc:  3e e4 a0 3b     cxbvc  %l2, 0x1b, 0xe0
+  e0:  01 00 00 00     nop 
diff --git a/gas/testsuite/gas/sparc/cbcond.s b/gas/testsuite/gas/sparc/cbcond.s
new file mode 100644 (file)
index 0000000..2d15243
--- /dev/null
@@ -0,0 +1,59 @@
+# Test CBCOND instructions
+       .text
+       cwbe    %o1, %o2,1f
+       cwbe    %o1, 2, 1f
+       cxbe    %o2, %o3, 1f
+       cxbe    %o2, 3, 1f
+       cwble   %o3, %o4, 1f
+       cwble   %o3, 4, 1f
+       cxble   %o4, %o5, 1f
+       cxble   %o4, 5, 1f
+       cwbl    %o5, %l0, 1f
+       cwbl    %o5, 6, 1f
+       cxbl    %l0, %l1, 1f
+       cxbl    %l0, 7, 1f
+       cwbleu  %l1, %l2, 1f
+       cwbleu  %l1, 8, 1f
+       cxbleu  %l2, %l3, 1f
+       cxbleu  %l2, 9, 1f
+       cwbcs   %l3, %l4, 1f
+       cwbcs   %l3, 10, 1f
+       cxbcs   %l4, %l5, 1f
+       cxbcs   %l4, 11, 1f
+       cwbneg  %l5, %l6, 1f
+       cwbneg  %l5, 12, 1f
+       cxbneg  %l6, %l7, 1f
+       cxbneg  %l6, 13, 1f
+       cwbvs   %l7, %i0, 1f
+       cwbvs   %l7, 14, 1f
+       cxbvs   %i0, %i1, 1f
+       cxbvs   %i0, 15, 1f
+       cwbne   %i1, %i2, 1f
+       cwbne   %i1, 16, 1f
+       cxbne   %i2, %i3, 1f
+       cxbne   %i2, 17, 1f
+       cwbg    %i3, %i4, 1f
+       cwbg    %i3, 18, 1f
+       cxbg    %i4, %i5, 1f
+       cxbg    %i4, 19, 1f
+       cwbge   %i5, %o0, 1f
+       cwbge   %i5, 20, 1f
+       cxbge   %o0, %o1, 1f
+       cxbge   %o0, 21, 1f
+       cwbgu   %o1, %o2, 1f
+       cwbgu   %o1, 22, 1f
+       cxbgu   %o2, %o3, 1f
+       cxbgu   %o2, 22, 1f
+       cwbcc   %o3, %o4, 1f
+       cwbcc   %o3, 23, 1f
+       cxbcc   %o4, %o5, 1f
+       cxbcc   %o4, 24, 1f
+       cwbpos  %o5, %l0, 1f
+       cwbpos  %o5, 25, 1f
+       cxbpos  %l0, %l1, 1f
+       cxbpos  %l0, 25, 1f
+       cwbvc   %l1, %l2, 1f
+       cwbvc   %l1, 26, 1f
+       cxbvc   %l2, %l3, 1f
+       cxbvc   %l2, 27, 1f
+1:     nop
index f2ad181253553e7fbb117f28a6dca1f953237bb7..e16421256687139e1c56170fc8c1eeb77f29dff9 100644 (file)
@@ -63,6 +63,7 @@ if [istarget sparc*-*-*] {
     run_dump_test "hpcvis3"
     run_dump_test "ima"
     run_dump_test "crypto"
+    run_dump_test "cbcond"
 
     run_list_test "pr4587" ""
 }
index a1e1fab554f42692f53c9d36928d9a16d17b3d48..c20461b7bb77e47afa1feecbcad33d85aac8cafb 100644 (file)
@@ -1,5 +1,10 @@
 2012-04-27  David S. Miller  <davem@davemloft.net>
 
+       * 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.
 
index 2ae6fd2bad4ef1497bd877e4bb453b94bebc9fc2..d83b49d3f02a14cbc8d8a0c98cbba69f5b3e27f6 100644 (file)
@@ -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 */
 \f
@@ -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 */