Module Name: src Committed By: matt Date: Wed Dec 18 14:07:30 UTC 2013
Modified Files: src/gnu/dist/binutils/gas/config [matt-nb5-mips64]: tc-arm.c src/gnu/dist/binutils/include/opcode [matt-nb5-mips64]: arm.h Log Message: Add some armv7 instructions. To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.5.32.1 src/gnu/dist/binutils/gas/config/tc-arm.c cvs rdiff -u -r1.1.1.2 -r1.1.1.2.32.1 \ src/gnu/dist/binutils/include/opcode/arm.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/gnu/dist/binutils/gas/config/tc-arm.c diff -u src/gnu/dist/binutils/gas/config/tc-arm.c:1.5 src/gnu/dist/binutils/gas/config/tc-arm.c:1.5.32.1 --- src/gnu/dist/binutils/gas/config/tc-arm.c:1.5 Thu Feb 2 22:03:54 2006 +++ src/gnu/dist/binutils/gas/config/tc-arm.c Wed Dec 18 14:07:30 2013 @@ -6651,25 +6651,35 @@ do_ldmstm (char * str) skip_whitespace (str); - if ((base_reg = reg_required_here (&str, 16)) == FAIL) - return; - - if (base_reg == REG_PC) + base_reg = (inst.instruction >> 16) & 0xf; + if (base_reg == 0) { - inst.error = _("r15 not allowed as base register"); - return; - } + if ((base_reg = reg_required_here (&str, 16)) == FAIL) + return; - skip_whitespace (str); + if (base_reg == REG_PC) + { + inst.error = _("r15 not allowed as base register"); + return; + } - if (*str == '!') - { - inst.instruction |= WRITE_BACK; - str++; + skip_whitespace (str); + + if (*str == '!') + { + inst.instruction |= WRITE_BACK; + str++; + } + + if (skip_past_comma (&str) == FAIL) + { + if (! inst.error) + inst.error = BAD_ARGS; + return; + } } - if (skip_past_comma (&str) == FAIL - || (range = reg_list (&str)) == FAIL) + if ((range = reg_list (&str)) == FAIL) { if (! inst.error) inst.error = BAD_ARGS; @@ -6746,6 +6756,231 @@ do_swi (char * str) } static void +do_dsb (char * str) +{ + skip_whitespace (str); + /* Allow optional leading '#'. */ + if (is_immediate_prefix (*str)) + str++; + + end_of_line (str); +} + +static void +do_movwt (char * str) +{ + expressionS expr; + int reg; + + skip_whitespace (str); + + if ((reg = reg_required_here (&str, 12)) == FAIL + || skip_past_comma (&str) == FAIL) + return; + + if (reg == REG_PC) + { + inst.error = BAD_PC; + return; + } + + if (is_immediate_prefix (*str)) + str++; + else + { + inst.error = _("immediate expression expected"); + return; + } + + if (my_get_expression (&expr, &str)) + return; + + if (expr.X_op != O_constant) + { + inst.error = _("constant expression expected"); + return; + } + + if ((expr.X_add_number & 0xffff0000) != 0) + { + inst.error = _("invalid unsigned 16-bit value"); + return; + } + + inst.instruction |= (expr.X_add_number & 0xf000) << 4; + inst.instruction |= (expr.X_add_number & 0x0fff); +} + +static void +do_bfci (char * str) +{ + expressionS expr; + unsigned long lsb; + unsigned long width; + int reg; + + skip_whitespace (str); + + if ((reg = reg_required_here (&str, 12)) == FAIL + || skip_past_comma (&str) == FAIL) + return; + + if (reg == REG_PC) + { + inst.error = BAD_PC; + return; + } + + if ((inst.instruction & 0xf) == 0) + { + if ((reg == reg_required_here (&str, 0)) == FAIL + || skip_past_comma (&str) == FAIL) + return; + + if (reg == REG_PC) + { + inst.error = BAD_PC; + return; + } + } + + if (is_immediate_prefix (*str)) + str++; + else + { + inst.error = _("immediate expression expected"); + return; + } + + if (my_get_expression (&expr, &str)) + return; + + if (expr.X_op != O_constant) + { + inst.error = _("constant expression expected"); + return; + } + + lsb = expr.X_add_number; + if (lsb > 31) + { + inst.error = _("invalid lsb"); + return; + } + + if (skip_past_comma (&str) == FAIL) + return; + + if (is_immediate_prefix (*str)) + str++; + else + { + inst.error = _("immediate expression expected"); + return; + } + + if (my_get_expression (&expr, &str)) + return; + + if (expr.X_op != O_constant) + { + inst.error = _("constant expression expected"); + return; + } + + width = expr.X_add_number; + if (lsb + width > 32 || width > 32 || width == 0) + { + if (!inst.error) + inst.error = _("invalid width"); + return; + } + + inst.instruction |= (lsb << 7); + inst.instruction |= (lsb + width - 1) << 16; + + end_of_line (str); +} + +static void +do_bfx (char * str) +{ + expressionS expr; + unsigned long lsb; + unsigned long width; + int rd, rn; + + skip_whitespace (str); + + if ((rd = reg_required_here (&str, 12)) == FAIL + || skip_past_comma (&str) == FAIL + || (rn = reg_required_here (&str, 0)) == FAIL + || skip_past_comma (&str) == FAIL) + { + inst.error = BAD_ARGS; + return; + } + else if (rd == REG_PC || rn == REG_PC) + { + inst.error = BAD_PC; + return; + } + + if (is_immediate_prefix (*str)) + str++; + else + { + inst.error = _("immediate expression expected"); + return; + } + + if (my_get_expression (&expr, &str)) + return; + + if (expr.X_op != O_constant) + { + inst.error = _("constant expression expected"); + return; + } + + lsb = expr.X_add_number; + if (lsb > 31) + { + inst.error = _("invalid lsb"); + return; + } + + if (skip_past_comma (&str) == FAIL) + { + inst.error = BAD_ARGS; + return; + } + + if (is_immediate_prefix (*str)) + str++; + else + { + inst.error = _("immediate expression expected"); + return; + } + + if (my_get_expression (&expr, &str)) + return; + + width = expr.X_add_number; + if (lsb + width > 32 || width > 32 || width == 0) + { + inst.error = _("invalid width"); + return; + } + + inst.instruction |= (lsb << 7); + inst.instruction |= (width - 1) << 16; + + end_of_line (str); +} + +static void do_swap (char * str) { int reg; @@ -9770,11 +10005,13 @@ static const struct asm_opcode insns[] = {"stmda", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm}, {"stmdb", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm}, {"stmfd", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm}, + {"push", 0xe92d0000, 4, ARM_EXT_V1, do_ldmstm}, {"stmfa", 0xe9800000, 3, ARM_EXT_V1, do_ldmstm}, {"stmea", 0xe8800000, 3, ARM_EXT_V1, do_ldmstm}, {"stmed", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm}, {"ldmia", 0xe8900000, 3, ARM_EXT_V1, do_ldmstm}, + {"pop", 0xe8bd0000, 3, ARM_EXT_V1, do_ldmstm}, {"ldmib", 0xe9900000, 3, ARM_EXT_V1, do_ldmstm}, {"ldmda", 0xe8100000, 3, ARM_EXT_V1, do_ldmstm}, {"ldmdb", 0xe9100000, 3, ARM_EXT_V1, do_ldmstm}, @@ -10014,6 +10251,17 @@ static const struct asm_opcode insns[] = /* ARM V6Z. */ { "smi", 0xe1600070, 3, ARM_EXT_V6Z, do_smi}, + /* ARM V7A. */ + { "bfi", 0xe7c00010, 3, ARM_EXT_V7A, do_bfci}, + { "bfc", 0xe7c0001f, 3, ARM_EXT_V7A, do_bfci}, + { "dmb", 0xf57ff05f, 0, ARM_EXT_V7A, do_dsb}, + { "dsb", 0xf57ff04f, 0, ARM_EXT_V7A, do_dsb}, + { "isb", 0xf57ff06f, 0, ARM_EXT_V7A, do_dsb}, + { "movw", 0xe3000000, 2, ARM_EXT_V7A, do_movwt}, + { "movt", 0xe3400000, 2, ARM_EXT_V7A, do_movwt}, + { "sbfx", 0xe7a00050, 4, ARM_EXT_V7A, do_bfx}, + { "ubfx", 0xe7e00050, 4, ARM_EXT_V7A, do_bfx}, + /* 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}, @@ -12714,6 +12962,8 @@ static struct arm_cpu_option_table arm_c {"mpcorenovfp", ARM_ARCH_V6K, FPU_NONE}, {"arm1176jz-s", ARM_ARCH_V6ZK, FPU_NONE}, {"arm1176jzf-s", ARM_ARCH_V6ZK, FPU_ARCH_VFP_V2}, + {"cortex-a8", ARM_ARCH_V7A, FPU_ARCH_VFP_V2}, + {"cortex-a9", ARM_ARCH_V7A, FPU_ARCH_VFP_V2}, /* ??? XSCALE is really an architecture. */ {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2}, /* ??? iwmmxt is not a processor. */ @@ -12757,6 +13007,8 @@ static struct arm_arch_option_table arm_ {"armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP}, {"armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP}, {"armv6zk", ARM_ARCH_V6ZK, FPU_ARCH_VFP}, + {"armv7", ARM_ARCH_V7A, FPU_ARCH_VFP}, + {"armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP}, {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP}, {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP}, {NULL, 0, 0} @@ -12965,6 +13217,20 @@ arm_parse_arch (char * str) return 0; } +static void +s_arch (int ignore ATTRIBUTE_UNUSED) +{ + char *name, *p, c; + SKIP_WHITESPACE (); + name = input_line_pointer; + c = get_symbol_end (); + p = input_line_pointer; + arm_parse_arch (name); + *p = c; + SKIP_WHITESPACE (); + demand_empty_rest_of_line (); +} + static int arm_parse_fpu (char * str) { @@ -14839,6 +15105,7 @@ const pseudo_typeS md_pseudo_table[] = { "unreq", s_unreq, 0 }, { "bss", s_bss, 0 }, { "align", s_align, 0 }, + { "arch", s_arch, 0 }, { "arm", s_arm, 0 }, { "thumb", s_thumb, 0 }, { "code", s_code, 0 }, Index: src/gnu/dist/binutils/include/opcode/arm.h diff -u src/gnu/dist/binutils/include/opcode/arm.h:1.1.1.2 src/gnu/dist/binutils/include/opcode/arm.h:1.1.1.2.32.1 --- src/gnu/dist/binutils/include/opcode/arm.h:1.1.1.2 Thu Feb 2 21:12:05 2006 +++ src/gnu/dist/binutils/include/opcode/arm.h Wed Dec 18 14:07:30 2013 @@ -34,6 +34,7 @@ #define ARM_EXT_V6 0x00001000 /* ARM V6. */ #define ARM_EXT_V6K 0x00002000 /* ARM V6K. */ #define ARM_EXT_V6Z 0x00004000 /* ARM V6Z. */ +#define ARM_EXT_V7A 0x00008000 /* ARM V7A. */ /* Co-processor space extensions. */ #define ARM_CEXT_XSCALE 0x00800000 /* Allow MIA etc. */ @@ -65,6 +66,7 @@ #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) +#define ARM_ARCH_V7A (ARM_ARCH_V6ZK | ARM_EXT_V7A) /* Processors with specific extensions in the co-processor space. */ #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_CEXT_XSCALE)