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)