From 0dd132b63cb935b9e55b4d2545bb70c9dc094dea Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 30 Sep 2004 16:21:50 +0000 Subject: [PATCH] Apply Paul Brook's patch to implement armv6k instructions --- bfd/ChangeLog | 6 +++ bfd/bfd-in2.h | 1 + bfd/libbfd.h | 1 + bfd/reloc.c | 2 + gas/ChangeLog | 10 ++++ gas/config/tc-arm.c | 89 ++++++++++++++++++++++++++++++++- gas/doc/c-arm.texi | 9 +++- gas/testsuite/ChangeLog | 6 +++ gas/testsuite/gas/arm/arch6zk.d | 28 +++++++++++ gas/testsuite/gas/arm/arch6zk.s | 27 ++++++++++ gas/testsuite/gas/arm/arm.exp | 1 + include/opcode/ChangeLog | 5 ++ include/opcode/arm.h | 5 ++ opcodes/ChangeLog | 5 ++ opcodes/arm-dis.c | 11 +++- opcodes/arm-opc.h | 40 +++++++++++---- 16 files changed, 232 insertions(+), 14 deletions(-) create mode 100644 gas/testsuite/gas/arm/arch6zk.d create mode 100644 gas/testsuite/gas/arm/arch6zk.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1d9635288d6..231242b485a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2004-09-30 Paul Brook + + * reloc.c: Add BFD_RELOC_ARM_SMI. + * bfd-in2.h: Regenerate. + * libbfd.h: Ditto. + 2004-09-24 Alan Modra * dwarf2.c (_bfd_dwarf2_find_nearest_line): Add output section diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 4be38cf7a3e..6feb83e2d8b 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2618,6 +2618,7 @@ field in the instruction. */ BFD_RELOC_ARM_ADRL_IMMEDIATE, BFD_RELOC_ARM_OFFSET_IMM, BFD_RELOC_ARM_SHIFT_IMM, + BFD_RELOC_ARM_SMI, BFD_RELOC_ARM_SWI, BFD_RELOC_ARM_MULTI, BFD_RELOC_ARM_CP_OFF_IMM, diff --git a/bfd/libbfd.h b/bfd/libbfd.h index abe6a2aca03..c079a6acaa8 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1111,6 +1111,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_ARM_ADRL_IMMEDIATE", "BFD_RELOC_ARM_OFFSET_IMM", "BFD_RELOC_ARM_SHIFT_IMM", + "BFD_RELOC_ARM_SMI", "BFD_RELOC_ARM_SWI", "BFD_RELOC_ARM_MULTI", "BFD_RELOC_ARM_CP_OFF_IMM", diff --git a/bfd/reloc.c b/bfd/reloc.c index 8356b6092f6..0069841eda4 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2559,6 +2559,8 @@ ENUMX BFD_RELOC_ARM_OFFSET_IMM ENUMX BFD_RELOC_ARM_SHIFT_IMM +ENUMX + BFD_RELOC_ARM_SMI ENUMX BFD_RELOC_ARM_SWI ENUMX diff --git a/gas/ChangeLog b/gas/ChangeLog index 5ee17b628dc..66b267ab1a0 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2004-09-30 Paul Brook + + * config/tc-arm.c (do_smi, do_nop): New functions. + (insns): Add ARMv6ZK instructions. + (md_apply_fix3): Handle BFD_RELOC_ARM_SMI. + (tc_gen_reloc): Ditto. + (arm_cpus): Add mpcore and arm1176. + (arm_archs): Add armv6{k,z,zk}. + * doc/c-arm.texi: Document new cores and architectures. + 2004-09-30 Nick Clifton * config/tc-arm.c: Use ISO C90 formatting. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index d9c873af3f5..752cd3c04a6 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -2499,6 +2499,41 @@ cp_byte_address_required_here (char ** str) return SUCCESS; } +static void +do_nop (char * str) +{ + skip_whitespace (str); + if (*str == '{') + { + str++; + + if (my_get_expression (&inst.reloc.exp, &str)) + inst.reloc.exp.X_op = O_illegal; + else + { + skip_whitespace (str); + if (*str == '}') + str++; + else + inst.reloc.exp.X_op = O_illegal; + } + + if (inst.reloc.exp.X_op != O_constant + || inst.reloc.exp.X_add_number > 255 + || inst.reloc.exp.X_add_number < 0) + { + inst.error = _("Invalid NOP hint"); + return; + } + + /* Arcitectural NOP hints are CPSR sets with no bits selected. */ + inst.instruction &= 0xf0000000; + inst.instruction |= 0x0320f000 + inst.reloc.exp.X_add_number; + } + + end_of_line (str); +} + static void do_empty (char * str) { @@ -4316,7 +4351,7 @@ do_pkhtb (char * str) } /* ARM V6 Load Register Exclusive instruction (argument parse). - LDREX{} ] + LDREX{,B,D,H}{} ] Condition defaults to COND_ALWAYS. Error if Rd or Rn are R15. See ARMARMv6 A4.1.27: LDREX. */ @@ -6634,6 +6669,23 @@ do_ldmstm (char * str) end_of_line (str); } +static void +do_smi (char * str) +{ + skip_whitespace (str); + + /* Allow optional leading '#'. */ + if (is_immediate_prefix (*str)) + str++; + + if (my_get_expression (& inst.reloc.exp, & str)) + return; + + inst.reloc.type = BFD_RELOC_ARM_SMI; + inst.reloc.pc_rel = 0; + end_of_line (str); +} + static void do_swi (char * str) { @@ -9791,7 +9843,7 @@ static const struct asm_opcode insns[] = /* Pseudo ops. */ {"adr", 0xe28f0000, 3, ARM_EXT_V1, do_adr}, {"adrl", 0xe28f0000, 3, ARM_EXT_V1, do_adrl}, - {"nop", 0xe1a00000, 3, ARM_EXT_V1, do_empty}, + {"nop", 0xe1a00000, 3, ARM_EXT_V1, do_nop}, /* ARM 2 multiplies. */ {"mul", 0xe0000090, 3, ARM_EXT_V2, do_mul}, @@ -9993,6 +10045,22 @@ static const struct asm_opcode insns[] = { "usat", 0xe6e00010, 4, ARM_EXT_V6, do_usat}, { "usat16", 0xe6e00f30, 6, ARM_EXT_V6, do_usat16}, + /* ARM V6K. */ + { "clrex", 0xf57ff01f, 0, ARM_EXT_V6K, do_empty}, + { "ldrexb", 0xe1d00f9f, 6, ARM_EXT_V6K, do_ldrex}, + { "ldrexd", 0xe1b00f9f, 6, ARM_EXT_V6K, do_ldrex}, + { "ldrexh", 0xe1f00f9f, 6, ARM_EXT_V6K, do_ldrex}, + { "sev", 0xe320f004, 3, ARM_EXT_V6K, do_empty}, + { "strexb", 0xe1c00f90, 6, ARM_EXT_V6K, do_strex}, + { "strexd", 0xe1a00f90, 6, ARM_EXT_V6K, do_strex}, + { "strexh", 0xe1e00f90, 6, ARM_EXT_V6K, do_strex}, + { "wfe", 0xe320f002, 3, ARM_EXT_V6K, do_empty}, + { "wfi", 0xe320f003, 3, ARM_EXT_V6K, do_empty}, + { "yield", 0xe320f001, 5, ARM_EXT_V6K, do_empty}, + + /* ARM V6Z. */ + { "smi", 0xe1600070, 3, ARM_EXT_V6Z, do_smi}, + /* Core FPA instruction set (V1). */ {"wfs", 0xee200110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl}, {"rfs", 0xee300110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl}, @@ -11650,6 +11718,15 @@ md_apply_fix3 (fixS * fixP, md_number_to_chars (buf, newval, INSN_SIZE); break; + case BFD_RELOC_ARM_SMI: + if (((unsigned long) value) > 0xffff) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("invalid smi expression")); + newval = md_chars_to_number (buf, INSN_SIZE) & 0xfff000f0; + newval |= (value & 0xf) | ((value & 0xfff0) << 4); + md_number_to_chars (buf, newval, INSN_SIZE); + break; + case BFD_RELOC_ARM_SWI: if (arm_data->thumb_mode) { @@ -12204,6 +12281,7 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, { case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break; case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break; + case BFD_RELOC_ARM_SMI: type = "SMI"; break; case BFD_RELOC_ARM_SWI: type = "SWI"; break; case BFD_RELOC_ARM_MULTI: type = "MULTI"; break; case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break; @@ -12740,6 +12818,10 @@ static struct arm_cpu_option_table arm_cpus[] = {"arm1136j-s", ARM_ARCH_V6, FPU_NONE}, {"arm1136jfs", ARM_ARCH_V6, FPU_ARCH_VFP_V2}, {"arm1136jf-s", ARM_ARCH_V6, FPU_ARCH_VFP_V2}, + {"mpcore", ARM_ARCH_V6K, FPU_ARCH_VFP_V2}, + {"mpcorenovfp", ARM_ARCH_V6K, FPU_NONE}, + {"arm1176jz-s", ARM_ARCH_V6ZK, FPU_NONE}, + {"arm1176jzf-s", ARM_ARCH_V6ZK, FPU_ARCH_VFP_V2}, /* ??? XSCALE is really an architecture. */ {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2}, /* ??? iwmmxt is not a processor. */ @@ -12780,6 +12862,9 @@ static struct arm_arch_option_table arm_archs[] = {"armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP}, {"armv6", ARM_ARCH_V6, FPU_ARCH_VFP}, {"armv6j", ARM_ARCH_V6, FPU_ARCH_VFP}, + {"armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP}, + {"armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP}, + {"armv6zk", ARM_ARCH_V6ZK, FPU_ARCH_VFP}, {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP}, {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP}, {NULL, 0, 0} diff --git a/gas/doc/c-arm.texi b/gas/doc/c-arm.texi index d8027d23182..cb4569b100d 100644 --- a/gas/doc/c-arm.texi +++ b/gas/doc/c-arm.texi @@ -1,4 +1,4 @@ -@c Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003 +@c Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004 @c Free Software Foundation, Inc. @c This is part of the GAS manual. @c For copying conditions, see the file as.texinfo. @@ -96,6 +96,10 @@ recognized: @code{arm1026ej-s}, @code{arm1136j-s}, @code{arm1136jf-s}, +@code{arm1176jz-s}, +@code{arm1176jzf-s}, +@code{mpcore}, +@code{mpcorenovfp}, @code{ep9312} (ARM920 with Cirrus Maverick coprocessor), @code{i80200} (Intel XScale processor) @code{iwmmxt} (Intel(r) XScale processor with Wireless MMX(tm) technology coprocessor) @@ -137,6 +141,9 @@ names are recognized: @code{armv5texp}, @code{armv6}, @code{armv6j}, +@code{armv6k}, +@code{armv6z}, +@code{armv6zk}, @code{iwmmxt} and @code{xscale}. diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index a99939c756c..e7cd66c2c5f 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2004-09-30 Paul Brook + + * gas/arm/arch6zk.d: New file. + * gas/arm/arch6zk.s: New file. + * gas/arm/arm.exp: Add them. + 2004-09-29 Alan Modra * gas/i386/secrel.s: Pad .rdata out to 16 byte boundary. diff --git a/gas/testsuite/gas/arm/arch6zk.d b/gas/testsuite/gas/arm/arch6zk.d new file mode 100644 index 00000000000..318e312b665 --- /dev/null +++ b/gas/testsuite/gas/arm/arch6zk.d @@ -0,0 +1,28 @@ +#name: ARM V6 instructions +#as: -march=armv6zk +#objdump: -dr --prefix-addresses --show-raw-insn + +.*: +file format .*arm.* + +Disassembly of section .text: +0+000 <[^>]*> f57ff01f ? clrex +0+004 <[^>]*> e1dc3f9f ? ldrexb r3, \[ip\] +0+008 <[^>]*> 11d3cf9f ? ldrexbne ip, \[r3\] +0+00c <[^>]*> e1bc3f9f ? ldrexd r3, \[ip\] +0+010 <[^>]*> 11b3cf9f ? ldrexdne ip, \[r3\] +0+014 <[^>]*> e1fc3f9f ? ldrexh r3, \[ip\] +0+018 <[^>]*> 11f3cf9f ? ldrexhne ip, \[r3\] +0+01c <[^>]*> e320f080 ? nop \{128\} +0+020 <[^>]*> 1320f07f ? nopne \{127\} +0+024 <[^>]*> e320f004 ? sev +0+028 <[^>]*> e1c73f9c ? strexb r3, ip, \[r7\] +0+02c <[^>]*> 11c8cf93 ? strexbne ip, r3, \[r8\] +0+030 <[^>]*> e1a73f9c ? strexd r3, ip, \[r7\] +0+034 <[^>]*> 11a8cf93 ? strexdne ip, r3, \[r8\] +0+038 <[^>]*> e1e73f9c ? strexh r3, ip, \[r7\] +0+03c <[^>]*> 11e8cf93 ? strexhne ip, r3, \[r8\] +0+040 <[^>]*> e320f002 ? wfe +0+044 <[^>]*> e320f003 ? wfi +0+048 <[^>]*> e320f001 ? yield +0+04c <[^>]*> e16ec371 ? smi 60465 +0+050 <[^>]*> 11613c7e ? smine 5070 diff --git a/gas/testsuite/gas/arm/arch6zk.s b/gas/testsuite/gas/arm/arch6zk.s new file mode 100644 index 00000000000..cf769be3d75 --- /dev/null +++ b/gas/testsuite/gas/arm/arch6zk.s @@ -0,0 +1,27 @@ +.text +.align 0 + +label: + # ARMV6K instructions + clrex + ldrexb r3, [r12] + ldrexbne r12, [r3] + ldrexd r3, [r12] + ldrexdne r12, [r3] + ldrexh r3, [r12] + ldrexhne r12, [r3] + nop {128} + nopne {127} + sev + strexb r3, r12, [r7] + strexbne r12, r3, [r8] + strexd r3, r12, [r7] + strexdne r12, r3, [r8] + strexh r3, r12, [r7] + strexhne r12, r3, [r8] + wfe + wfi + yield + # ARMV6Z instructions + smi 0xec31 + smine 0x13ce diff --git a/gas/testsuite/gas/arm/arm.exp b/gas/testsuite/gas/arm/arm.exp index 16361d9dff9..732468a0a45 100644 --- a/gas/testsuite/gas/arm/arm.exp +++ b/gas/testsuite/gas/arm/arm.exp @@ -50,6 +50,7 @@ if {[istarget *arm*-*-*] || [istarget "xscale-*-*"]} then { run_dump_test "maverick" run_dump_test "archv6" run_dump_test "thumbv6" + run_dump_test "arch6zk" run_errors_test "vfp-bad" "-mfpu=vfp" "VFP errors" run_errors_test "req" "-mcpu=arm7m" ".req errors" diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 462165c45cf..6d75eee9973 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,8 @@ +2004-09-30 Paul Brook + + * arm.h (ARM_EXT_V6K, ARM_EXT_V6Z): Define. + (ARM_ARCH_V6K, ARM_ARCH_V6Z, ARM_ARCH_V6ZK): Define. + 2004-09-11 Theodore A. Roth * avr.h: Add support for diff --git a/include/opcode/arm.h b/include/opcode/arm.h index 6ccccbd4eca..dd90e2ac669 100644 --- a/include/opcode/arm.h +++ b/include/opcode/arm.h @@ -32,6 +32,8 @@ #define ARM_EXT_V5E 0x00000400 /* DSP Double transfers. */ #define ARM_EXT_V5J 0x00000800 /* Jazelle extension. */ #define ARM_EXT_V6 0x00001000 /* ARM V6. */ +#define ARM_EXT_V6K 0x00002000 /* ARM V6K. */ +#define ARM_EXT_V6Z 0x00004000 /* ARM V6Z. */ /* Co-processor space extensions. */ #define ARM_CEXT_XSCALE 0x00800000 /* Allow MIA etc. */ @@ -60,6 +62,9 @@ #define ARM_ARCH_V5TE (ARM_ARCH_V5TExP | ARM_EXT_V5E) #define ARM_ARCH_V5TEJ (ARM_ARCH_V5TE | ARM_EXT_V5J) #define ARM_ARCH_V6 (ARM_ARCH_V5TEJ | ARM_EXT_V6) +#define ARM_ARCH_V6K (ARM_ARCH_V6 | ARM_EXT_V6K) +#define ARM_ARCH_V6Z (ARM_ARCH_V6 | ARM_EXT_V6Z) +#define ARM_ARCH_V6ZK (ARM_ARCH_V6 | ARM_EXT_V6K | ARM_EXT_V6Z) /* Processors with specific extensions in the co-processor space. */ #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_CEXT_XSCALE) diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index f4eebbbe19c..cf49121abec 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,8 @@ +2004-09-30 Paul Brook + + * arm-dis.c (print_insn_arm): Handle 'e' for SMI instruction. + * arm-opc.h: Document %e. Add ARMv6ZK instructions. + 2004-09-17 H.J. Lu * Makefile.am (AUTOMAKE_OPTIONS): Require 1.9. diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index e918dafa28b..44cdeac3449 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -1,5 +1,5 @@ /* Instruction printing code for the ARM - Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) Modification by James G. Smith (jsmith@cygnus.co.uk) @@ -900,6 +900,15 @@ print_insn_arm (pc, info, given) } break; + case 'e': + { + int imm; + + imm = (given & 0xf) | ((given & 0xfff00) >> 4); + func (stream, "%d", imm); + } + break; + default: abort (); } diff --git a/opcodes/arm-opc.h b/opcodes/arm-opc.h index 4b52f131719..531f4587ae9 100644 --- a/opcodes/arm-opc.h +++ b/opcodes/arm-opc.h @@ -1,6 +1,6 @@ /* Opcode table for the ARM. - Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2003 + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2003, 2004 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify @@ -18,18 +18,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -struct arm_opcode { - unsigned long value, mask; /* recognise instruction if (op&mask)==value */ - char *assembler; /* how to disassemble this instruction */ +struct arm_opcode +{ + unsigned long value, mask; /* Recognise instruction if (op&mask)==value. */ + char *assembler; /* How to disassemble this instruction. */ }; struct thumb_opcode { - unsigned short value, mask; /* recognise instruction if (op&mask)==value */ - char * assembler; /* how to disassemble this instruction */ + unsigned short value, mask; /* Recognise instruction if (op&mask)==value. */ + char * assembler; /* How to disassemble this instruction. */ }; -/* format of the assembler string : +/* Format of the assembler string : %% % %d print the bitfield in decimal @@ -82,10 +83,10 @@ Thumb specific format options: %W print (bitfield * 4) as a decimal %H print (bitfield * 2) as a decimal %a print (bitfield * 4) as a pc-rel offset + decoded symbol -*/ + %e print arm SMI operand (bits 0..7,8..19). */ /* Note: There is a partial ordering in this table - it must be searched from - the top to obtain a correct match. */ + the top to obtain a correct match. */ static const struct arm_opcode arm_opcodes[] = { @@ -98,7 +99,26 @@ static const struct arm_opcode arm_opcodes[] = {0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"}, {0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"}, - /* ARM V6 instructions. */ + /* ARM V6Z instructions. */ + {0x01600070, 0x0ff000f0, "smi%c\t%e"}, + + /* ARM V6K instructions. */ + {0xf57ff01f, 0xffffffff, "clrex"}, + {0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"}, + {0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"}, + {0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"}, + {0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"}, + {0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"}, + {0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"}, + + /* ARM V6K NOP hints. */ + {0x0320f001, 0x0fffffff, "yield"}, + {0x0320f002, 0x0fffffff, "wfe"}, + {0x0320f003, 0x0fffffff, "wfi"}, + {0x0320f004, 0x0fffffff, "sev"}, + {0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"}, + + /* ARM V6 instructions. */ {0xfc500000, 0xfff00000, "mrrc2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, {0xfc400000, 0xfff00000, "mcrr2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, {0xf1080000, 0xfffdfe3f, "cpsie\t%8'a%7'i%6'f"}, -- 2.30.2