diff options
-rw-r--r-- | gas/ChangeLog | 9 | ||||
-rw-r--r-- | gas/config/tc-arm.c | 61 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/armv8-a-barrier-arm.d | 24 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/armv8-a-barrier-thumb.d | 24 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/armv8-a-barrier.s | 18 | ||||
-rw-r--r-- | opcodes/ChangeLog | 6 | ||||
-rw-r--r-- | opcodes/arm-dis.c | 62 |
8 files changed, 169 insertions, 41 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 5d6b4449f8..da593838d4 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +2012-08-24 Matthew Gretton-Dann <matthew.gretton-dann@arm.com> + + * config/tc-arm.c (asm_barrier_opt): Add arch field. + (mark_feature_used): New function. + (parse_barrier): Check specified option is valid for the + specified architecture. + (UL_BARRIER): New macro. + (barrier_opt_names): Update for new barrier options. + 2012-08-24 Matthew Gretton-Dann <matthew.gretton-dann@arm.com> * config/tc-arm.c (do_setend): Warn on deprecated SETEND. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 8f2f88bd96..d3838abeb8 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -461,8 +461,9 @@ struct asm_psr struct asm_barrier_opt { - const char * template_name; - unsigned long value; + const char * template_name; + unsigned long value; + const arm_feature_set arch; }; /* The bit that distinguishes CPSR and SPSR. */ @@ -5766,6 +5767,25 @@ parse_cond (char **str) return c->value; } +/* If the given feature available in the selected CPU, mark it as used. + Returns TRUE iff feature is available. */ +static bfd_boolean +mark_feature_used (const arm_feature_set *feature) +{ + /* Ensure the option is valid on the current architecture. */ + if (!ARM_CPU_HAS_FEATURE (cpu_variant, *feature)) + return FALSE; + + /* Add the appropriate architecture feature for the barrier option used. + */ + if (thumb_mode) + ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, *feature); + else + ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, *feature); + + return TRUE; +} + /* Parse an option for a barrier instruction. Returns the encoding for the option, or FAIL. */ static int @@ -5783,6 +5803,9 @@ parse_barrier (char **str) if (!o) return FAIL; + if (!mark_feature_used (&o->arch)) + return FAIL; + *str = q; return o->value; } @@ -17170,22 +17193,32 @@ static const struct asm_cond conds[] = {"al", 0xe} }; +#define UL_BARRIER(L,U,CODE,FEAT) \ + { L, CODE, ARM_FEATURE (FEAT, 0) }, \ + { U, CODE, ARM_FEATURE (FEAT, 0) } + static struct asm_barrier_opt barrier_opt_names[] = { - { "sy", 0xf }, { "SY", 0xf }, - { "un", 0x7 }, { "UN", 0x7 }, - { "st", 0xe }, { "ST", 0xe }, - { "unst", 0x6 }, { "UNST", 0x6 }, - { "ish", 0xb }, { "ISH", 0xb }, - { "sh", 0xb }, { "SH", 0xb }, - { "ishst", 0xa }, { "ISHST", 0xa }, - { "shst", 0xa }, { "SHST", 0xa }, - { "nsh", 0x7 }, { "NSH", 0x7 }, - { "nshst", 0x6 }, { "NSHST", 0x6 }, - { "osh", 0x3 }, { "OSH", 0x3 }, - { "oshst", 0x2 }, { "OSHST", 0x2 } + UL_BARRIER ("sy", "SY", 0xf, ARM_EXT_BARRIER), + UL_BARRIER ("st", "ST", 0xe, ARM_EXT_BARRIER), + UL_BARRIER ("ld", "LD", 0xd, ARM_EXT_V8), + UL_BARRIER ("ish", "ISH", 0xb, ARM_EXT_BARRIER), + UL_BARRIER ("sh", "SH", 0xb, ARM_EXT_BARRIER), + UL_BARRIER ("ishst", "ISHST", 0xa, ARM_EXT_BARRIER), + UL_BARRIER ("shst", "SHST", 0xa, ARM_EXT_BARRIER), + UL_BARRIER ("ishld", "ISHLD", 0x9, ARM_EXT_V8), + UL_BARRIER ("un", "UN", 0x7, ARM_EXT_BARRIER), + UL_BARRIER ("nsh", "NSH", 0x7, ARM_EXT_BARRIER), + UL_BARRIER ("unst", "UNST", 0x6, ARM_EXT_BARRIER), + UL_BARRIER ("nshst", "NSHST", 0x6, ARM_EXT_BARRIER), + UL_BARRIER ("nshld", "NSHLD", 0x5, ARM_EXT_V8), + UL_BARRIER ("osh", "OSH", 0x3, ARM_EXT_BARRIER), + UL_BARRIER ("oshst", "OSHST", 0x2, ARM_EXT_BARRIER), + UL_BARRIER ("oshld", "OSHLD", 0x1, ARM_EXT_V8) }; +#undef UL_BARRIER + /* Table of ARM-format instructions. */ /* Macros for gluing together operand strings. N.B. In all cases diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 2cdaada1d5..d70a2c68e7 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2012-08-24 Matthew Gretton-Dann <matthew.gretton-dann@arm.com> + * gas/arm/armv8-a-barrier.s: New testcase. + * gas/arm/armv8-a-barrier-arm.d: Likewise. + * gas/arm/armv8-a-barrier-thumb.d: Likewise. + +2012-08-24 Matthew Gretton-Dann <matthew.gretton-dann@arm.com> + * gas/arm/armv8-a-bad.l: Update * gas/arm/armv8-a-bad.s: Likewise. diff --git a/gas/testsuite/gas/arm/armv8-a-barrier-arm.d b/gas/testsuite/gas/arm/armv8-a-barrier-arm.d new file mode 100644 index 0000000000..1a245fa92d --- /dev/null +++ b/gas/testsuite/gas/arm/armv8-a-barrier-arm.d @@ -0,0 +1,24 @@ +#name: Valid v8-A barrier (ARM) +#as: -march=armv8-a +#source: armv8-a-barrier.s +#objdump: -dr --prefix-addresses --show-raw-insn + +.*: +file format .*arm.* + +Disassembly of section .text: +0[0-9a-f]+ <[^>]+> f57ff04d dsb ld +0[0-9a-f]+ <[^>]+> f57ff049 dsb ishld +0[0-9a-f]+ <[^>]+> f57ff045 dsb nshld +0[0-9a-f]+ <[^>]+> f57ff041 dsb oshld +0[0-9a-f]+ <[^>]+> f57ff05d dmb ld +0[0-9a-f]+ <[^>]+> f57ff059 dmb ishld +0[0-9a-f]+ <[^>]+> f57ff055 dmb nshld +0[0-9a-f]+ <[^>]+> f57ff051 dmb oshld +0[0-9a-f]+ <[^>]+> f57ff04d dsb ld +0[0-9a-f]+ <[^>]+> f57ff049 dsb ishld +0[0-9a-f]+ <[^>]+> f57ff045 dsb nshld +0[0-9a-f]+ <[^>]+> f57ff041 dsb oshld +0[0-9a-f]+ <[^>]+> f57ff05d dmb ld +0[0-9a-f]+ <[^>]+> f57ff059 dmb ishld +0[0-9a-f]+ <[^>]+> f57ff055 dmb nshld +0[0-9a-f]+ <[^>]+> f57ff051 dmb oshld diff --git a/gas/testsuite/gas/arm/armv8-a-barrier-thumb.d b/gas/testsuite/gas/arm/armv8-a-barrier-thumb.d new file mode 100644 index 0000000000..42dae15686 --- /dev/null +++ b/gas/testsuite/gas/arm/armv8-a-barrier-thumb.d @@ -0,0 +1,24 @@ +#name: Valid v8-A barrier (Thumb) +#as: -march=armv8-a -mthumb +#source: armv8-a-barrier.s +#objdump: -dr --prefix-addresses --show-raw-insn + +.*: +file format .*arm.* + +Disassembly of section .text: +0[0-9a-f]+ <[^>]+> f3bf 8f4d dsb ld +0[0-9a-f]+ <[^>]+> f3bf 8f49 dsb ishld +0[0-9a-f]+ <[^>]+> f3bf 8f45 dsb nshld +0[0-9a-f]+ <[^>]+> f3bf 8f41 dsb oshld +0[0-9a-f]+ <[^>]+> f3bf 8f5d dmb ld +0[0-9a-f]+ <[^>]+> f3bf 8f59 dmb ishld +0[0-9a-f]+ <[^>]+> f3bf 8f55 dmb nshld +0[0-9a-f]+ <[^>]+> f3bf 8f51 dmb oshld +0[0-9a-f]+ <[^>]+> f3bf 8f4d dsb ld +0[0-9a-f]+ <[^>]+> f3bf 8f49 dsb ishld +0[0-9a-f]+ <[^>]+> f3bf 8f45 dsb nshld +0[0-9a-f]+ <[^>]+> f3bf 8f41 dsb oshld +0[0-9a-f]+ <[^>]+> f3bf 8f5d dmb ld +0[0-9a-f]+ <[^>]+> f3bf 8f59 dmb ishld +0[0-9a-f]+ <[^>]+> f3bf 8f55 dmb nshld +0[0-9a-f]+ <[^>]+> f3bf 8f51 dmb oshld diff --git a/gas/testsuite/gas/arm/armv8-a-barrier.s b/gas/testsuite/gas/arm/armv8-a-barrier.s new file mode 100644 index 0000000000..f7b71c0cc4 --- /dev/null +++ b/gas/testsuite/gas/arm/armv8-a-barrier.s @@ -0,0 +1,18 @@ + .syntax unified + .text + dsb ld + dsb ishld + dsb nshld + dsb oshld + dmb ld + dmb ishld + dmb nshld + dmb oshld + dsb LD + dsb ISHLD + dsb NSHLD + dsb OSHLD + dmb LD + dmb ISHLD + dmb NSHLD + dmb OSHLD diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 6a1db6d9ad..2b60eb5b78 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,9 @@ +2012-08-24 Matthew Gretton-Dann <matthew.gretton-dann@arm.com> + + * arm-dis.c (data_barrier_option): New function. + (print_insn_arm): Use data_barrier_option. + (print_insn_thumb32): Use data_barrier_option. + 2012-08-24 Matthew Gretton-Dann <matthew.gretton-dann@arm.com * arm-dis.c (COND_UNCOND): New constant. diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index 532a6c8c8d..ccbb6b327c 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -863,6 +863,8 @@ static const struct opcode32 arm_opcodes[] = /* V7 instructions. */ {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"}, {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"}, + {ARM_EXT_V8, 0xf57ff051, 0xfffffff3, "dmb\t%U"}, + {ARM_EXT_V8, 0xf57ff041, 0xfffffff3, "dsb\t%U"}, {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"}, {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"}, {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"}, @@ -1414,6 +1416,8 @@ static const struct opcode32 thumb32_opcodes[] = /* V7 instructions. */ {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"}, {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"}, + {ARM_EXT_V8, 0xf3bf8f51, 0xfffffff3, "dmb%c\t%U"}, + {ARM_EXT_V8, 0xf3bf8f41, 0xfffffff3, "dsb%c\t%U"}, {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"}, {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"}, {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"}, @@ -2985,6 +2989,28 @@ banked_regname (unsigned reg) } } +/* Return the name of the DMB/DSB option. */ +static const char * +data_barrier_option (unsigned option) +{ + switch (option & 0xf) + { + case 0xf: return "sy"; + case 0xe: return "st"; + case 0xd: return "ld"; + case 0xb: return "ish"; + case 0xa: return "ishst"; + case 0x9: return "ishld"; + case 0x7: return "un"; + case 0x6: return "unst"; + case 0x5: return "nshld"; + case 0x3: return "osh"; + case 0x2: return "oshst"; + case 0x1: return "oshld"; + default: return NULL; + } +} + /* Print one ARM instruction from PC on INFO->STREAM. */ static void @@ -3335,20 +3361,11 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) } else { - switch (given & 0xf) - { - case 0xf: func (stream, "sy"); break; - case 0x7: func (stream, "un"); break; - case 0xe: func (stream, "st"); break; - case 0x6: func (stream, "unst"); break; - case 0xb: func (stream, "ish"); break; - case 0xa: func (stream, "ishst"); break; - case 0x3: func (stream, "osh"); break; - case 0x2: func (stream, "oshst"); break; - default: + const char * opt = data_barrier_option (given & 0xf); + if (opt != NULL) + func (stream, "%s", opt); + else func (stream, "#%d", (int) given & 0xf); - break; - } } break; @@ -4222,20 +4239,11 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) } else { - switch (given & 0xf) - { - case 0xf: func (stream, "sy"); break; - case 0x7: func (stream, "un"); break; - case 0xe: func (stream, "st"); break; - case 0x6: func (stream, "unst"); break; - case 0xb: func (stream, "ish"); break; - case 0xa: func (stream, "ishst"); break; - case 0x3: func (stream, "osh"); break; - case 0x2: func (stream, "oshst"); break; - default: - func (stream, "#%d", (int) given & 0xf); - break; - } + const char * opt = data_barrier_option (given & 0xf); + if (opt != NULL) + func (stream, "%s", opt); + else + func (stream, "#%d", (int) given & 0xf); } break; |