diff options
author | David S. Miller <davem@redhat.com> | 2012-04-27 18:03:13 +0000 |
---|---|---|
committer | David S. Miller <davem@redhat.com> | 2012-04-27 18:03:13 +0000 |
commit | 698544e152e041de8aaaaeea99f6f3c00ee99604 (patch) | |
tree | 264045c30492ca6144e246820391c0b5cf651a1d /gas | |
parent | 6cda13266f4d767456ccd5ee9f4c8539b463fc0e (diff) | |
download | binutils-698544e152e041de8aaaaeea99f6f3c00ee99604.zip binutils-698544e152e041de8aaaaeea99f6f3c00ee99604.tar.gz binutils-698544e152e041de8aaaaeea99f6f3c00ee99604.tar.bz2 |
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 'gas')
-rw-r--r-- | gas/ChangeLog | 6 | ||||
-rw-r--r-- | gas/config/tc-sparc.c | 30 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/cbcond.d | 66 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/cbcond.s | 59 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/sparc.exp | 1 |
6 files changed, 161 insertions, 5 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index ff8b2ff..ca23ecb 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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 diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index f2f0ae8..3e95357 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -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; diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index a3b3a32..478a4de 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -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 index 0000000..d094045 --- /dev/null +++ b/gas/testsuite/gas/sparc/cbcond.d @@ -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 index 0000000..2d15243 --- /dev/null +++ b/gas/testsuite/gas/sparc/cbcond.s @@ -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 diff --git a/gas/testsuite/gas/sparc/sparc.exp b/gas/testsuite/gas/sparc/sparc.exp index f2ad181..e164212 100644 --- a/gas/testsuite/gas/sparc/sparc.exp +++ b/gas/testsuite/gas/sparc/sparc.exp @@ -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" "" } |