* ARMv6T2 ARM instructions - assembler support
@ 2005-03-14 23:22 Zack Weinberg
2005-03-15 3:51 ` Zack Weinberg
2005-03-15 10:07 ` Richard Earnshaw
0 siblings, 2 replies; 5+ messages in thread
From: Zack Weinberg @ 2005-03-14 23:22 UTC (permalink / raw)
To: binutils
This patch adds assembler support for the new ARM-format instructions
in ARMv6T2, and tests for them (and hence also for the disassembler
patch I committed last week).
zw
gas:
* config/tc-arm.c (do_mla): Rename to do_mlas, take second
is_mls parameter.
(do_mla, do_mls, five_bit_unsigned_immediate, bfci_lsb_and_width)
(do_bfc, do_bfi, do_bfx, do_rbit, do_mov16, do_ldsttv4): New functions.
(insns): Add ARMv6T2 instructions:
bfc bfi mls movw movt rbit sbfx ubfx ldrht ldrsht ldrsbt strht.
(arm_archs): Add V6T2 variants.
gas/testsuite:
* gas/arm/archv6t2.d, gas/arm/archv6t2.s: New dump test.
* gas/arm/archv6t2-bad.l, gas/arm/archv6t2-bad.l: New errors test.
* gas/arm/arm.exp: Run them.
===================================================================
Index: config/tc-arm.c
--- config/tc-arm.c 12 Mar 2005 18:25:46 -0000 1.194
+++ config/tc-arm.c 14 Mar 2005 23:18:08 -0000
@@ -2814,7 +2814,7 @@ do_mul (char * str)
}
static void
-do_mla (char * str)
+do_mlas (char * str, bfd_boolean is_mls)
{
int rd, rm;
@@ -2847,7 +2847,12 @@ do_mla (char * str)
}
if (rm == rd)
- as_tsktsk (_("rd and rm should be different in mla"));
+ {
+ if (is_mls)
+ as_tsktsk (_("rd and rm should be different in mls"));
+ else
+ as_tsktsk (_("rd and rm should be different in mla"));
+ }
if (skip_past_comma (&str) == FAIL
|| (rd = reg_required_here (&str, 8)) == FAIL
@@ -2867,6 +2872,18 @@ do_mla (char * str)
end_of_line (str);
}
+static void
+do_mla (char *str)
+{
+ do_mlas (str, FALSE);
+}
+
+static void
+do_mls (char *str)
+{
+ do_mlas (str, TRUE);
+}
+
/* Expects *str -> the characters "acc0", possibly with leading blanks.
Advances *str to the next non-alphanumeric.
Returns 0, or else FAIL (in which case sets inst.error).
@@ -4512,6 +4529,286 @@ do_cpsi (char * str)
end_of_line (str);
}
+/* ARM V6T2 bitfield manipulation instructions. */
+
+static int
+five_bit_unsigned_immediate (char **str)
+{
+ expressionS expr;
+
+ skip_whitespace (*str);
+ if (!is_immediate_prefix (**str))
+ {
+ inst.error = _("immediate expression expected");
+ return -1;
+ }
+ (*str)++;
+ if (my_get_expression (&expr, str))
+ {
+ inst.error = _("bad expression");
+ return -1;
+ }
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("constant expression expected");
+ return -1;
+ }
+ if (expr.X_add_number < 0 || expr.X_add_number > 32)
+ {
+ inst.error = _("immediate value out of range");
+ return -1;
+ }
+
+ return expr.X_add_number;
+}
+
+static void
+bfci_lsb_and_width (char *str)
+{
+ int lsb, width;
+
+ if ((lsb = five_bit_unsigned_immediate (&str)) == -1)
+ return;
+
+ if (skip_past_comma (&str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ if ((width = five_bit_unsigned_immediate (&str)) == -1)
+ return;
+
+ end_of_line (str);
+
+ if (width == 0 || lsb == 32)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+ else if (width + lsb > 32)
+ {
+ inst.error = _("bit-field extends past end of register");
+ return;
+ }
+
+ /* Convert to LSB/MSB and write to register. */
+ inst.instruction |= lsb << 7;
+ inst.instruction |= (width + lsb - 1) << 16;
+}
+
+static void
+do_bfc (char *str)
+{
+ int rd;
+
+ /* Rd. */
+ skip_whitespace (str);
+ if (((rd = reg_required_here (&str, 12)) == FAIL)
+ || (skip_past_comma (&str) == FAIL))
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ else if (rd == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ bfci_lsb_and_width (str);
+}
+
+static void
+do_bfi (char *str)
+{
+ int rd, rm;
+
+ /* Rd. */
+ skip_whitespace (str);
+ if (((rd = reg_required_here (&str, 12)) == FAIL)
+ || (skip_past_comma (&str) == FAIL))
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ else if (rd == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ /* Rm. Accept #0 in this position as an alternative syntax for bfc. */
+ skip_whitespace (str);
+ if (is_immediate_prefix (*str))
+ {
+ expressionS expr;
+ str++;
+ if (my_get_expression (&expr, &str))
+ {
+ inst.error = _("bad expression");
+ return;
+ }
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("constant expression expected");
+ return;
+ }
+ if (expr.X_add_number != 0)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+ inst.instruction |= 0x0000000f; /* Rm = PC -> bfc, not bfi. */
+ }
+ else
+ {
+ if ((rm = reg_required_here (&str, 0)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ else if (rm == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+ }
+ if (skip_past_comma (&str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ bfci_lsb_and_width (str);
+}
+
+static void
+do_bfx (char *str)
+{
+ int lsb, width;
+
+ /* Rd. */
+ skip_whitespace (str);
+ if (reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ /* Rm. */
+ skip_whitespace (str);
+ if (reg_required_here (&str, 0) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if ((lsb = five_bit_unsigned_immediate (&str)) == -1)
+ return;
+
+ if (skip_past_comma (&str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ if ((width = five_bit_unsigned_immediate (&str)) == -1)
+ return;
+
+ end_of_line (str);
+
+ if (width == 0 || lsb == 32)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+ else if (width + lsb > 32)
+ {
+ inst.error = _("bit-field extends past end of register");
+ return;
+ }
+
+ inst.instruction |= lsb << 7;
+ inst.instruction |= (width - 1) << 16;
+}
+
+static void
+do_rbit (char *str)
+{
+ /* Rd. */
+ skip_whitespace (str);
+ if (reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ /* Rm. */
+ skip_whitespace (str);
+ if (reg_required_here (&str, 0) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+/* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>. */
+static void
+do_mov16 (char *str)
+{
+ int rd;
+ expressionS expr;
+
+ /* Rd. */
+ skip_whitespace (str);
+ if (((rd = reg_required_here (&str, 12)) == FAIL)
+ || (skip_past_comma (&str) == FAIL))
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ else if (rd == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ /* Imm16. */
+ skip_whitespace (str);
+ if (!is_immediate_prefix (*str))
+ {
+ inst.error = _("immediate expression expected");
+ return;
+ }
+ str++;
+ if (my_get_expression (&expr, &str))
+ {
+ inst.error = _("bad expression");
+ return;
+ }
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("constant expression expected");
+ return;
+ }
+ if (expr.X_add_number < 0 || expr.X_add_number > 65535)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+
+ end_of_line (str);
+
+ /* The value is in two pieces: 0:11, 16:19. */
+ inst.instruction |= (expr.X_add_number & 0x00000fff);
+ inst.instruction |= (expr.X_add_number & 0x0000f000) << 4;
+}
+
+
/* THUMB V5 breakpoint instruction (argument parse)
BKPT <immed_8>. */
@@ -6517,6 +6814,84 @@ do_ldstv4 (char * str)
end_of_line (str);
}
+static void
+do_ldsttv4 (char * str)
+{
+ int conflict_reg;
+
+ skip_whitespace (str);
+
+ if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL)
+ {
+ inst.error = _("address expected");
+ return;
+ }
+
+ if (*str == '[')
+ {
+ int reg;
+
+ str++;
+
+ skip_whitespace (str);
+
+ if ((reg = reg_required_here (&str, 16)) == FAIL)
+ return;
+
+ /* ldrt/strt always use post-indexed addressing, so if the base is
+ the same as Rd, we warn. */
+ if (conflict_reg == reg)
+ as_warn (_("%s register same as write-back base"),
+ ((inst.instruction & LOAD_BIT)
+ ? _("destination") : _("source")));
+
+ skip_whitespace (str);
+
+ if (*str == ']')
+ {
+ str ++;
+
+ if (skip_past_comma (&str) == SUCCESS)
+ {
+ /* [Rn],... (post inc) */
+ if (ldst_extend_v4 (&str) == FAIL)
+ return;
+ }
+ else
+ {
+ /* [Rn] */
+ skip_whitespace (str);
+
+ /* Skip a write-back '!'. */
+ if (*str == '!')
+ str++;
+
+ inst.instruction |= (INDEX_UP|HWOFFSET_IMM);
+ }
+ }
+ else
+ {
+ inst.error = _("post-indexed expression expected");
+ return;
+ }
+ }
+ else
+ {
+ inst.error = _("post-indexed expression expected");
+ return;
+ }
+
+ end_of_line (str);
+}
+
+
static long
reg_list (char ** strp)
{
@@ -10014,6 +10389,21 @@ static const struct asm_opcode insns[] =
/* ARM V6Z. */
{ "smi", 0xe1600070, 3, ARM_EXT_V6Z, do_smi},
+ /* ARM V6T2. */
+ { "bfc", 0xe7c0001f, 3, ARM_EXT_V6T2, do_bfc},
+ { "bfi", 0xe7c00010, 3, ARM_EXT_V6T2, do_bfi},
+ { "mls", 0xe0600090, 3, ARM_EXT_V6T2, do_mls},
+ { "movw", 0xe3000000, 4, ARM_EXT_V6T2, do_mov16},
+ { "movt", 0xe3400000, 4, ARM_EXT_V6T2, do_mov16},
+ { "rbit", 0xe3ff0f30, 4, ARM_EXT_V6T2, do_rbit},
+ { "sbfx", 0xe7a00050, 4, ARM_EXT_V6T2, do_bfx},
+ { "ubfx", 0xe7e00050, 4, ARM_EXT_V6T2, do_bfx},
+
+ { "ldrht", 0xe03000b0, 3, ARM_EXT_V6T2, do_ldsttv4},
+ { "ldrsht", 0xe03000f0, 3, ARM_EXT_V6T2, do_ldsttv4},
+ { "ldrsbt", 0xe03000d0, 3, ARM_EXT_V6T2, do_ldsttv4},
+ { "strht", 0xe02000b0, 3, ARM_EXT_V6T2, do_ldsttv4},
+
/* 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},
@@ -12763,6 +13153,10 @@ 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},
+ {"armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP},
+ {"armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP},
+ {"armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP},
+ {"armv6zkt2", ARM_ARCH_V6ZKT2, FPU_ARCH_VFP},
{"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP},
{"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
{NULL, 0, 0}
===================================================================
Index: testsuite/gas/arm/archv6t2-bad.l
--- testsuite/gas/arm/archv6t2-bad.l 1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/arm/archv6t2-bad.l 14 Mar 2005 23:18:08 -0000
@@ -0,0 +1,40 @@
+[^:]*: Assembler messages:
+[^:]*:6: Error: r15 not allowed here -- `bfc pc,#0,#1'
+[^:]*:7: Error: r15 not allowed here -- `bfi pc,r0,#0,#1'
+[^:]*:8: Error: r15 not allowed here -- `movw pc,#0'
+[^:]*:9: Error: r15 not allowed here -- `movt pc,#0'
+[^:]*:12: Error: immediate value out of range -- `bfc r0,#0,#0'
+[^:]*:13: Error: immediate value out of range -- `bfc r0,#32,#0'
+[^:]*:14: Error: immediate value out of range -- `bfc r0,#0,#33'
+[^:]*:15: Error: immediate value out of range -- `bfc r0,#33,#1'
+[^:]*:16: Error: immediate value out of range -- `bfc r0,#32,#1'
+[^:]*:17: Error: bit-field extends past end of register -- `bfc r0,#28,#10'
+[^:]*:19: Error: immediate value out of range -- `bfi r0,r1,#0,#0'
+[^:]*:20: Error: immediate value out of range -- `bfi r0,r1,#32,#0'
+[^:]*:21: Error: immediate value out of range -- `bfi r0,r1,#0,#33'
+[^:]*:22: Error: immediate value out of range -- `bfi r0,r1,#33,#1'
+[^:]*:23: Error: immediate value out of range -- `bfi r0,r1,#32,#1'
+[^:]*:24: Error: bit-field extends past end of register -- `bfi r0,r1,#28,#10'
+[^:]*:26: Error: immediate value out of range -- `sbfx r0,r1,#0,#0'
+[^:]*:27: Error: immediate value out of range -- `sbfx r0,r1,#32,#0'
+[^:]*:28: Error: immediate value out of range -- `sbfx r0,r1,#0,#33'
+[^:]*:29: Error: immediate value out of range -- `sbfx r0,r1,#33,#1'
+[^:]*:30: Error: immediate value out of range -- `sbfx r0,r1,#32,#1'
+[^:]*:31: Error: bit-field extends past end of register -- `sbfx r0,r1,#28,#10'
+[^:]*:33: Error: immediate value out of range -- `ubfx r0,r1,#0,#0'
+[^:]*:34: Error: immediate value out of range -- `ubfx r0,r1,#32,#0'
+[^:]*:35: Error: immediate value out of range -- `ubfx r0,r1,#0,#33'
+[^:]*:36: Error: immediate value out of range -- `ubfx r0,r1,#33,#1'
+[^:]*:37: Error: immediate value out of range -- `ubfx r0,r1,#32,#1'
+[^:]*:38: Error: bit-field extends past end of register -- `ubfx r0,r1,#28,#10'
+[^:]*:41: Error: immediate value out of range -- `bfi r0,#1,#2,#3'
+[^:]*:44: Error: immediate value out of range -- `movt r0,#65537'
+[^:]*:45: Error: immediate value out of range -- `movw r0,#65537'
+[^:]*:46: Error: immediate value out of range -- `movt r0,#-1'
+[^:]*:47: Error: immediate value out of range -- `movw r0,#-1'
+[^:]*:50: rd and rm should be different in mla
+[^:]*:51: rd and rm should be different in mls
+[^:]*:54: Warning: destination register same as write-back base
+[^:]*:55: Warning: destination register same as write-back base
+[^:]*:56: Warning: destination register same as write-back base
+[^:]*:57: Warning: source register same as write-back base
===================================================================
Index: testsuite/gas/arm/archv6t2-bad.s
--- testsuite/gas/arm/archv6t2-bad.s 1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/arm/archv6t2-bad.s 14 Mar 2005 23:18:08 -0000
@@ -0,0 +1,57 @@
+ @ We do not bother testing simple cases, e.g. immediates where
+ @ registers belong, trailing junk at end of line.
+ .text
+x:
+ @ pc not allowed
+ bfc pc,#0,#1
+ bfi pc,r0,#0,#1
+ movw pc,#0
+ movt pc,#0
+
+ @ bitfield range limits
+ bfc r0,#0,#0
+ bfc r0,#32,#0
+ bfc r0,#0,#33
+ bfc r0,#33,#1
+ bfc r0,#32,#1
+ bfc r0,#28,#10
+
+ bfi r0,r1,#0,#0
+ bfi r0,r1,#32,#0
+ bfi r0,r1,#0,#33
+ bfi r0,r1,#33,#1
+ bfi r0,r1,#32,#1
+ bfi r0,r1,#28,#10
+
+ sbfx r0,r1,#0,#0
+ sbfx r0,r1,#32,#0
+ sbfx r0,r1,#0,#33
+ sbfx r0,r1,#33,#1
+ sbfx r0,r1,#32,#1
+ sbfx r0,r1,#28,#10
+
+ ubfx r0,r1,#0,#0
+ ubfx r0,r1,#32,#0
+ ubfx r0,r1,#0,#33
+ ubfx r0,r1,#33,#1
+ ubfx r0,r1,#32,#1
+ ubfx r0,r1,#28,#10
+
+ @ bfi accepts only #0 in Rm position
+ bfi r0,#1,#2,#3
+
+ @ mov16 range limits
+ movt r0,#65537
+ movw r0,#65537
+ movt r0,#-1
+ movw r0,#-1
+
+ @ mla, mls Rd == Rm (warning)
+ mla r0,r0,r1,r2
+ mls r0,r0,r1,r2
+
+ @ ldsttv4 Rd == Rn (warning)
+ ldrht r0,[r0]
+ ldrsbt r0,[r0]
+ ldrsht r0,[r0]
+ strht r0,[r0]
===================================================================
Index: testsuite/gas/arm/archv6t2.d
--- testsuite/gas/arm/archv6t2.d 1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/arm/archv6t2.d 14 Mar 2005 23:18:08 -0000
@@ -0,0 +1,48 @@
+#name: ARM V6T2 instructions
+#as: -march=armv6t2
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+00 <[^>]+> e7c2009f bfc r0, #1, #2
+0+04 <[^>]+> 17c2009f bfcne r0, #1, #2
+0+08 <[^>]+> e7c82213 bfi r2, r3, #4, #5
+0+0c <[^>]+> 17c82213 bfine r2, r3, #4, #5
+0+10 <[^>]+> e7c8221f bfc r2, #4, #5
+0+14 <[^>]+> 17c8221f bfcne r2, #4, #5
+0+18 <[^>]+> e7a532d4 sbfx r3, r4, #5, #6
+0+1c <[^>]+> 17a532d4 sbfxne r3, r4, #5, #6
+0+20 <[^>]+> e7e64355 ubfx r4, r5, #6, #7
+0+24 <[^>]+> 17e64355 ubfxne r4, r5, #6, #7
+0+28 <[^>]+> e3ff5f36 rbit r5, r6
+0+2c <[^>]+> 13ff5f36 rbitne r5, r6
+0+30 <[^>]+> e069cb9a mls r9, sl, fp, ip
+0+34 <[^>]+> 1069cb9a mlsne r9, sl, fp, ip
+0+38 <[^>]+> e301a234 movw sl, #4660 ; 0x1234
+0+3c <[^>]+> 1301a234 movwne sl, #4660 ; 0x1234
+0+40 <[^>]+> e345b678 movt fp, #22136 ; 0x5678
+0+44 <[^>]+> 1345b678 movtne fp, #22136 ; 0x5678
+0+48 <[^>]+> e0f760b0 ldrht r6, \[r7\]
+0+4c <[^>]+> 10f760b0 ldrneht r6, \[r7\]
+0+50 <[^>]+> e0b870b0 ldrht r7, \[r8\], r0
+0+54 <[^>]+> e03870b0 ldrht r7, \[r8\], -r0
+0+58 <[^>]+> e0f980ba ldrht r8, \[r9\], #10
+0+5c <[^>]+> e07980ba ldrht r8, \[r9\], #-10
+0+60 <[^>]+> e0f760f0 ldrsht r6, \[r7\]
+0+64 <[^>]+> 10f760f0 ldrnesht r6, \[r7\]
+0+68 <[^>]+> e0b870f0 ldrsht r7, \[r8\], r0
+0+6c <[^>]+> e03870f0 ldrsht r7, \[r8\], -r0
+0+70 <[^>]+> e0f980fa ldrsht r8, \[r9\], #10
+0+74 <[^>]+> e07980fa ldrsht r8, \[r9\], #-10
+0+78 <[^>]+> e0f760d0 ldrsbt r6, \[r7\]
+0+7c <[^>]+> 10f760d0 ldrnesbt r6, \[r7\]
+0+80 <[^>]+> e0b870d0 ldrsbt r7, \[r8\], r0
+0+84 <[^>]+> e03870d0 ldrsbt r7, \[r8\], -r0
+0+88 <[^>]+> e0f980da ldrsbt r8, \[r9\], #10
+0+8c <[^>]+> e0e760b0 strht r6, \[r7\]
+0+90 <[^>]+> 10e760b0 strneht r6, \[r7\]
+0+94 <[^>]+> e0a870b0 strh r7, \[r8\], r0
+0+98 <[^>]+> e02870b0 strh r7, \[r8\], -r0
+0+9c <[^>]+> e0e980ba strht r8, \[r9\], #10
+0+a0 <[^>]+> e06980ba strht r8, \[r9\], #-10
===================================================================
Index: testsuite/gas/arm/archv6t2.s
--- testsuite/gas/arm/archv6t2.s 1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/arm/archv6t2.s 14 Mar 2005 23:18:08 -0000
@@ -0,0 +1,51 @@
+ .text
+x:
+ bfc r0, #1, #2
+ bfcne r0, #1, #2
+ bfi r2, r3, #4, #5
+ bfine r2, r3, #4, #5
+ bfi r2, #0, #4, #5
+ bfine r2, #0, #4, #5
+
+ sbfx r3, r4, #5, #6
+ sbfxne r3, r4, #5, #6
+ ubfx r4, r5, #6, #7
+ ubfxne r4, r5, #6, #7
+
+ rbit r5, r6
+ rbitne r5, r6
+
+ mls r9, r10, r11, r12
+ mlsne r9, r10, r11, r12
+
+ movw r10, #0x1234
+ movwne r10, #0x1234
+ movt r11, #0x5678
+ movtne r11, #0x5678
+
+ ldrht r6, [r7]
+ ldrneht r6, [r7]
+ ldrht r7, [r8], r0
+ ldrht r7, [r8], -r0
+ ldrht r8, [r9], #10
+ ldrht r8, [r9], #-10
+
+ ldrsht r6, [r7]
+ ldrnesht r6, [r7]
+ ldrsht r7, [r8], r0
+ ldrsht r7, [r8], -r0
+ ldrsht r8, [r9], #10
+ ldrsht r8, [r9], #-10
+
+ ldrsbt r6, [r7]
+ ldrnesbt r6, [r7]
+ ldrsbt r7, [r8], r0
+ ldrsbt r7, [r8], -r0
+ ldrsbt r8, [r9], #10
+
+ strht r6, [r7]
+ strneht r6, [r7]
+ strht r7, [r8], r0
+ strht r7, [r8], -r0
+ strht r8, [r9], #10
+ strht r8, [r9], #-10
===================================================================
Index: testsuite/gas/arm/arm.exp
--- testsuite/gas/arm/arm.exp 12 Mar 2005 18:25:47 -0000 1.36
+++ testsuite/gas/arm/arm.exp 14 Mar 2005 23:18:08 -0000
@@ -49,6 +49,7 @@ if {[istarget *arm*-*-*] || [istarget "x
run_dump_test "reg-alias"
run_dump_test "maverick"
run_dump_test "archv6"
+ run_dump_test "archv6t2"
run_dump_test "thumbv6"
run_dump_test "thumbv6k"
run_dump_test "arch6zk"
@@ -57,6 +58,7 @@ if {[istarget *arm*-*-*] || [istarget "x
run_errors_test "req" "-mcpu=arm7m" ".req errors"
run_errors_test "armv1-bad" "-mcpu=arm7m" "ARM v1 errors"
run_errors_test "r15-bad" "" "Invalid use of r15 errors"
+ run_errors_test "archv6t2-bad" "-march=armv6t2" "Invalid V6T2 instructions"
if {[istarget *-*-*coff] || [istarget *-*-pe] || [istarget *-*-wince] ||
[istarget *-*-*aout*] || [istarget *-*-netbsd] || [istarget *-*-riscix*]} then {
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: ARMv6T2 ARM instructions - assembler support
2005-03-14 23:22 ARMv6T2 ARM instructions - assembler support Zack Weinberg
@ 2005-03-15 3:51 ` Zack Weinberg
2005-03-15 10:07 ` Richard Earnshaw
1 sibling, 0 replies; 5+ messages in thread
From: Zack Weinberg @ 2005-03-15 3:51 UTC (permalink / raw)
To: binutils
Something I neglected to mention. The ARM-ARM suggests that MOVT and
MOVW should be synthesized by the assembler for MOV immediates that
can't be expressed by a <shifter_operand>. I did not implement this.
Also, it's possible to intuit from the existence of relocations for
these instructions in the Mar 8 revision of ARMELF, that they should
allow most link-time expressions as well as bare immediates. I did
not implement that, either. (Both are in the pipeline.)
zw
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: ARMv6T2 ARM instructions - assembler support
2005-03-14 23:22 ARMv6T2 ARM instructions - assembler support Zack Weinberg
2005-03-15 3:51 ` Zack Weinberg
@ 2005-03-15 10:07 ` Richard Earnshaw
2005-03-15 20:38 ` Zack Weinberg
1 sibling, 1 reply; 5+ messages in thread
From: Richard Earnshaw @ 2005-03-15 10:07 UTC (permalink / raw)
To: Zack Weinberg; +Cc: binutils
On Mon, 2005-03-14 at 23:21, Zack Weinberg wrote:
> This patch adds assembler support for the new ARM-format instructions
> in ARMv6T2, and tests for them (and hence also for the disassembler
> patch I committed last week).
>
> zw
>
> gas:
> * config/tc-arm.c (do_mla): Rename to do_mlas, take second
> is_mls parameter.
> (do_mla, do_mls, five_bit_unsigned_immediate, bfci_lsb_and_width)
> (do_bfc, do_bfi, do_bfx, do_rbit, do_mov16, do_ldsttv4): New functions.
> (insns): Add ARMv6T2 instructions:
> bfc bfi mls movw movt rbit sbfx ubfx ldrht ldrsht ldrsbt strht.
> (arm_archs): Add V6T2 variants.
> gas/testsuite:
> * gas/arm/archv6t2.d, gas/arm/archv6t2.s: New dump test.
> * gas/arm/archv6t2-bad.l, gas/arm/archv6t2-bad.l: New errors test.
> * gas/arm/arm.exp: Run them.
>
> @@ -2847,7 +2847,12 @@ do_mla (char * str)
> }
>
> if (rm == rd)
> - as_tsktsk (_("rd and rm should be different in mla"));
> + {
> + if (is_mls)
> + as_tsktsk (_("rd and rm should be different in mls"));
> + else
> + as_tsktsk (_("rd and rm should be different in mla"));
> + }
>
mls doesn't have this restriction. v6 lifted the restriction for mla
too, and in practice all v4 or later cores don't have it either, but
that's hard to fix with the current -mcpu=all implementation.
OK apart from that.
R.
PS.
Just a note on the way I normally write tests. For each class of
instruction (a do_xxx function) I try to write a test pattern that sets
the minimal number of bits in the insn (eg uses r0 everywhere possible)
and then one pattern for each register (to check that each register is
setting the right bits). Finally, if the instruction is conditional, at
least one pattern should test this case.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: ARMv6T2 ARM instructions - assembler support
2005-03-15 10:07 ` Richard Earnshaw
@ 2005-03-15 20:38 ` Zack Weinberg
2005-03-16 14:30 ` Richard Earnshaw
0 siblings, 1 reply; 5+ messages in thread
From: Zack Weinberg @ 2005-03-15 20:38 UTC (permalink / raw)
To: Richard Earnshaw; +Cc: binutils
Richard Earnshaw <rearnsha@gcc.gnu.org> writes:
> mls doesn't have this restriction. v6 lifted the restriction for mla
> too, and in practice all v4 or later cores don't have it either, but
> that's hard to fix with the current -mcpu=all implementation.
>
> OK apart from that.
>
> R.
>
> PS.
>
> Just a note on the way I normally write tests. For each class of
> instruction (a do_xxx function) I try to write a test pattern that sets
> the minimal number of bits in the insn (eg uses r0 everywhere possible)
> and then one pattern for each register (to check that each register is
> setting the right bits). Finally, if the instruction is conditional, at
> least one pattern should test this case.
I have checked in the appended patch which removes the mls diagnostic
and revises the basic test the way you suggest. (r9 is used because
that sets the bits at either end of the register field - similarly for
17/18 in bit number fields.) Thanks for reviewing.
zw
* config/tc-arm.c (do_mla): Rename to do_mlas, take second
is_mls parameter; do not diagnose Rm==Rd when is_mls.
(do_mla, do_mls, five_bit_unsigned_immediate, bfci_lsb_and_width)
(do_bfc, do_bfi, do_bfx, do_rbit, do_mov16, do_ldsttv4): New functions.
(insns): Add ARMv6T2 instructions:
bfc bfi mls movw movt rbit sbfx ubfx ldrht ldrsht ldrsbt strht.
(arm_archs): Add V6T2 variants.
testsuite:
* gas/arm/archv6t2.d, gas/arm/archv6t2.s: New dump test.
* gas/arm/archv6t2-bad.l, gas/arm/archv6t2-bad.l: New errors test.
* gas/arm/arm.exp: Run them.
===================================================================
Index: config/tc-arm.c
--- config/tc-arm.c 12 Mar 2005 18:25:46 -0000 1.194
+++ config/tc-arm.c 15 Mar 2005 20:34:34 -0000
@@ -2814,7 +2814,7 @@ do_mul (char * str)
}
static void
-do_mla (char * str)
+do_mlas (char * str, bfd_boolean is_mls)
{
int rd, rm;
@@ -2846,7 +2846,9 @@ do_mla (char * str)
return;
}
- if (rm == rd)
+ /* This restriction does not apply to mls (nor to mla in v6, but
+ that's hard to detect at present). */
+ if (rm == rd && !is_mls)
as_tsktsk (_("rd and rm should be different in mla"));
if (skip_past_comma (&str) == FAIL
@@ -2867,6 +2869,18 @@ do_mla (char * str)
end_of_line (str);
}
+static void
+do_mla (char *str)
+{
+ do_mlas (str, FALSE);
+}
+
+static void
+do_mls (char *str)
+{
+ do_mlas (str, TRUE);
+}
+
/* Expects *str -> the characters "acc0", possibly with leading blanks.
Advances *str to the next non-alphanumeric.
Returns 0, or else FAIL (in which case sets inst.error).
@@ -4512,6 +4526,286 @@ do_cpsi (char * str)
end_of_line (str);
}
+/* ARM V6T2 bitfield manipulation instructions. */
+
+static int
+five_bit_unsigned_immediate (char **str)
+{
+ expressionS expr;
+
+ skip_whitespace (*str);
+ if (!is_immediate_prefix (**str))
+ {
+ inst.error = _("immediate expression expected");
+ return -1;
+ }
+ (*str)++;
+ if (my_get_expression (&expr, str))
+ {
+ inst.error = _("bad expression");
+ return -1;
+ }
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("constant expression expected");
+ return -1;
+ }
+ if (expr.X_add_number < 0 || expr.X_add_number > 32)
+ {
+ inst.error = _("immediate value out of range");
+ return -1;
+ }
+
+ return expr.X_add_number;
+}
+
+static void
+bfci_lsb_and_width (char *str)
+{
+ int lsb, width;
+
+ if ((lsb = five_bit_unsigned_immediate (&str)) == -1)
+ return;
+
+ if (skip_past_comma (&str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ if ((width = five_bit_unsigned_immediate (&str)) == -1)
+ return;
+
+ end_of_line (str);
+
+ if (width == 0 || lsb == 32)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+ else if (width + lsb > 32)
+ {
+ inst.error = _("bit-field extends past end of register");
+ return;
+ }
+
+ /* Convert to LSB/MSB and write to register. */
+ inst.instruction |= lsb << 7;
+ inst.instruction |= (width + lsb - 1) << 16;
+}
+
+static void
+do_bfc (char *str)
+{
+ int rd;
+
+ /* Rd. */
+ skip_whitespace (str);
+ if (((rd = reg_required_here (&str, 12)) == FAIL)
+ || (skip_past_comma (&str) == FAIL))
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ else if (rd == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ bfci_lsb_and_width (str);
+}
+
+static void
+do_bfi (char *str)
+{
+ int rd, rm;
+
+ /* Rd. */
+ skip_whitespace (str);
+ if (((rd = reg_required_here (&str, 12)) == FAIL)
+ || (skip_past_comma (&str) == FAIL))
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ else if (rd == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ /* Rm. Accept #0 in this position as an alternative syntax for bfc. */
+ skip_whitespace (str);
+ if (is_immediate_prefix (*str))
+ {
+ expressionS expr;
+ str++;
+ if (my_get_expression (&expr, &str))
+ {
+ inst.error = _("bad expression");
+ return;
+ }
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("constant expression expected");
+ return;
+ }
+ if (expr.X_add_number != 0)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+ inst.instruction |= 0x0000000f; /* Rm = PC -> bfc, not bfi. */
+ }
+ else
+ {
+ if ((rm = reg_required_here (&str, 0)) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ else if (rm == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+ }
+ if (skip_past_comma (&str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ bfci_lsb_and_width (str);
+}
+
+static void
+do_bfx (char *str)
+{
+ int lsb, width;
+
+ /* Rd. */
+ skip_whitespace (str);
+ if (reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ /* Rm. */
+ skip_whitespace (str);
+ if (reg_required_here (&str, 0) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if ((lsb = five_bit_unsigned_immediate (&str)) == -1)
+ return;
+
+ if (skip_past_comma (&str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ if ((width = five_bit_unsigned_immediate (&str)) == -1)
+ return;
+
+ end_of_line (str);
+
+ if (width == 0 || lsb == 32)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+ else if (width + lsb > 32)
+ {
+ inst.error = _("bit-field extends past end of register");
+ return;
+ }
+
+ inst.instruction |= lsb << 7;
+ inst.instruction |= (width - 1) << 16;
+}
+
+static void
+do_rbit (char *str)
+{
+ /* Rd. */
+ skip_whitespace (str);
+ if (reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ /* Rm. */
+ skip_whitespace (str);
+ if (reg_required_here (&str, 0) == FAIL)
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+/* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>. */
+static void
+do_mov16 (char *str)
+{
+ int rd;
+ expressionS expr;
+
+ /* Rd. */
+ skip_whitespace (str);
+ if (((rd = reg_required_here (&str, 12)) == FAIL)
+ || (skip_past_comma (&str) == FAIL))
+ {
+ inst.error = BAD_ARGS;
+ return;
+ }
+ else if (rd == REG_PC)
+ {
+ inst.error = BAD_PC;
+ return;
+ }
+
+ /* Imm16. */
+ skip_whitespace (str);
+ if (!is_immediate_prefix (*str))
+ {
+ inst.error = _("immediate expression expected");
+ return;
+ }
+ str++;
+ if (my_get_expression (&expr, &str))
+ {
+ inst.error = _("bad expression");
+ return;
+ }
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("constant expression expected");
+ return;
+ }
+ if (expr.X_add_number < 0 || expr.X_add_number > 65535)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+
+ end_of_line (str);
+
+ /* The value is in two pieces: 0:11, 16:19. */
+ inst.instruction |= (expr.X_add_number & 0x00000fff);
+ inst.instruction |= (expr.X_add_number & 0x0000f000) << 4;
+}
+
+
/* THUMB V5 breakpoint instruction (argument parse)
BKPT <immed_8>. */
@@ -6517,6 +6811,84 @@ do_ldstv4 (char * str)
end_of_line (str);
}
+static void
+do_ldsttv4 (char * str)
+{
+ int conflict_reg;
+
+ skip_whitespace (str);
+
+ if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = BAD_ARGS;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL)
+ {
+ inst.error = _("address expected");
+ return;
+ }
+
+ if (*str == '[')
+ {
+ int reg;
+
+ str++;
+
+ skip_whitespace (str);
+
+ if ((reg = reg_required_here (&str, 16)) == FAIL)
+ return;
+
+ /* ldrt/strt always use post-indexed addressing, so if the base is
+ the same as Rd, we warn. */
+ if (conflict_reg == reg)
+ as_warn (_("%s register same as write-back base"),
+ ((inst.instruction & LOAD_BIT)
+ ? _("destination") : _("source")));
+
+ skip_whitespace (str);
+
+ if (*str == ']')
+ {
+ str ++;
+
+ if (skip_past_comma (&str) == SUCCESS)
+ {
+ /* [Rn],... (post inc) */
+ if (ldst_extend_v4 (&str) == FAIL)
+ return;
+ }
+ else
+ {
+ /* [Rn] */
+ skip_whitespace (str);
+
+ /* Skip a write-back '!'. */
+ if (*str == '!')
+ str++;
+
+ inst.instruction |= (INDEX_UP|HWOFFSET_IMM);
+ }
+ }
+ else
+ {
+ inst.error = _("post-indexed expression expected");
+ return;
+ }
+ }
+ else
+ {
+ inst.error = _("post-indexed expression expected");
+ return;
+ }
+
+ end_of_line (str);
+}
+
+
static long
reg_list (char ** strp)
{
@@ -10014,6 +10386,21 @@ static const struct asm_opcode insns[] =
/* ARM V6Z. */
{ "smi", 0xe1600070, 3, ARM_EXT_V6Z, do_smi},
+ /* ARM V6T2. */
+ { "bfc", 0xe7c0001f, 3, ARM_EXT_V6T2, do_bfc},
+ { "bfi", 0xe7c00010, 3, ARM_EXT_V6T2, do_bfi},
+ { "mls", 0xe0600090, 3, ARM_EXT_V6T2, do_mls},
+ { "movw", 0xe3000000, 4, ARM_EXT_V6T2, do_mov16},
+ { "movt", 0xe3400000, 4, ARM_EXT_V6T2, do_mov16},
+ { "rbit", 0xe3ff0f30, 4, ARM_EXT_V6T2, do_rbit},
+ { "sbfx", 0xe7a00050, 4, ARM_EXT_V6T2, do_bfx},
+ { "ubfx", 0xe7e00050, 4, ARM_EXT_V6T2, do_bfx},
+
+ { "ldrht", 0xe03000b0, 3, ARM_EXT_V6T2, do_ldsttv4},
+ { "ldrsht", 0xe03000f0, 3, ARM_EXT_V6T2, do_ldsttv4},
+ { "ldrsbt", 0xe03000d0, 3, ARM_EXT_V6T2, do_ldsttv4},
+ { "strht", 0xe02000b0, 3, ARM_EXT_V6T2, do_ldsttv4},
+
/* 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},
@@ -12763,6 +13150,10 @@ 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},
+ {"armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP},
+ {"armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP},
+ {"armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP},
+ {"armv6zkt2", ARM_ARCH_V6ZKT2, FPU_ARCH_VFP},
{"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP},
{"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
{NULL, 0, 0}
===================================================================
Index: testsuite/gas/arm/archv6t2-bad.l
--- testsuite/gas/arm/archv6t2-bad.l 1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/arm/archv6t2-bad.l 15 Mar 2005 20:34:34 -0000
@@ -0,0 +1,38 @@
+[^:]*: Assembler messages:
+[^:]*:6: Error: r15 not allowed here -- `bfc pc,#0,#1'
+[^:]*:7: Error: r15 not allowed here -- `bfi pc,r0,#0,#1'
+[^:]*:8: Error: r15 not allowed here -- `movw pc,#0'
+[^:]*:9: Error: r15 not allowed here -- `movt pc,#0'
+[^:]*:12: Error: immediate value out of range -- `bfc r0,#0,#0'
+[^:]*:13: Error: immediate value out of range -- `bfc r0,#32,#0'
+[^:]*:14: Error: immediate value out of range -- `bfc r0,#0,#33'
+[^:]*:15: Error: immediate value out of range -- `bfc r0,#33,#1'
+[^:]*:16: Error: immediate value out of range -- `bfc r0,#32,#1'
+[^:]*:17: Error: bit-field extends past end of register -- `bfc r0,#28,#10'
+[^:]*:19: Error: immediate value out of range -- `bfi r0,r1,#0,#0'
+[^:]*:20: Error: immediate value out of range -- `bfi r0,r1,#32,#0'
+[^:]*:21: Error: immediate value out of range -- `bfi r0,r1,#0,#33'
+[^:]*:22: Error: immediate value out of range -- `bfi r0,r1,#33,#1'
+[^:]*:23: Error: immediate value out of range -- `bfi r0,r1,#32,#1'
+[^:]*:24: Error: bit-field extends past end of register -- `bfi r0,r1,#28,#10'
+[^:]*:26: Error: immediate value out of range -- `sbfx r0,r1,#0,#0'
+[^:]*:27: Error: immediate value out of range -- `sbfx r0,r1,#32,#0'
+[^:]*:28: Error: immediate value out of range -- `sbfx r0,r1,#0,#33'
+[^:]*:29: Error: immediate value out of range -- `sbfx r0,r1,#33,#1'
+[^:]*:30: Error: immediate value out of range -- `sbfx r0,r1,#32,#1'
+[^:]*:31: Error: bit-field extends past end of register -- `sbfx r0,r1,#28,#10'
+[^:]*:33: Error: immediate value out of range -- `ubfx r0,r1,#0,#0'
+[^:]*:34: Error: immediate value out of range -- `ubfx r0,r1,#32,#0'
+[^:]*:35: Error: immediate value out of range -- `ubfx r0,r1,#0,#33'
+[^:]*:36: Error: immediate value out of range -- `ubfx r0,r1,#33,#1'
+[^:]*:37: Error: immediate value out of range -- `ubfx r0,r1,#32,#1'
+[^:]*:38: Error: bit-field extends past end of register -- `ubfx r0,r1,#28,#10'
+[^:]*:41: Error: immediate value out of range -- `bfi r0,#1,#2,#3'
+[^:]*:44: Error: immediate value out of range -- `movt r0,#65537'
+[^:]*:45: Error: immediate value out of range -- `movw r0,#65537'
+[^:]*:46: Error: immediate value out of range -- `movt r0,#-1'
+[^:]*:47: Error: immediate value out of range -- `movw r0,#-1'
+[^:]*:50: Warning: destination register same as write-back base
+[^:]*:51: Warning: destination register same as write-back base
+[^:]*:52: Warning: destination register same as write-back base
+[^:]*:53: Warning: source register same as write-back base
===================================================================
Index: testsuite/gas/arm/archv6t2-bad.s
--- testsuite/gas/arm/archv6t2-bad.s 1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/arm/archv6t2-bad.s 15 Mar 2005 20:34:34 -0000
@@ -0,0 +1,53 @@
+ @ We do not bother testing simple cases, e.g. immediates where
+ @ registers belong, trailing junk at end of line.
+ .text
+x:
+ @ pc not allowed
+ bfc pc,#0,#1
+ bfi pc,r0,#0,#1
+ movw pc,#0
+ movt pc,#0
+
+ @ bitfield range limits
+ bfc r0,#0,#0
+ bfc r0,#32,#0
+ bfc r0,#0,#33
+ bfc r0,#33,#1
+ bfc r0,#32,#1
+ bfc r0,#28,#10
+
+ bfi r0,r1,#0,#0
+ bfi r0,r1,#32,#0
+ bfi r0,r1,#0,#33
+ bfi r0,r1,#33,#1
+ bfi r0,r1,#32,#1
+ bfi r0,r1,#28,#10
+
+ sbfx r0,r1,#0,#0
+ sbfx r0,r1,#32,#0
+ sbfx r0,r1,#0,#33
+ sbfx r0,r1,#33,#1
+ sbfx r0,r1,#32,#1
+ sbfx r0,r1,#28,#10
+
+ ubfx r0,r1,#0,#0
+ ubfx r0,r1,#32,#0
+ ubfx r0,r1,#0,#33
+ ubfx r0,r1,#33,#1
+ ubfx r0,r1,#32,#1
+ ubfx r0,r1,#28,#10
+
+ @ bfi accepts only #0 in Rm position
+ bfi r0,#1,#2,#3
+
+ @ mov16 range limits
+ movt r0,#65537
+ movw r0,#65537
+ movt r0,#-1
+ movw r0,#-1
+
+ @ ldsttv4 Rd == Rn (warning)
+ ldrht r0,[r0]
+ ldrsbt r0,[r0]
+ ldrsht r0,[r0]
+ strht r0,[r0]
===================================================================
Index: testsuite/gas/arm/archv6t2.d
--- testsuite/gas/arm/archv6t2.d 1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/arm/archv6t2.d 15 Mar 2005 20:34:34 -0000
@@ -0,0 +1,51 @@
+#name: ARM V6T2 instructions
+#as: -march=armv6t2
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+00 <[^>]+> e7c00010 bfi r0, r0, #0, #1
+0+04 <[^>]+> 17c00010 bfine r0, r0, #0, #1
+0+08 <[^>]+> e7c09010 bfi r9, r0, #0, #1
+0+0c <[^>]+> e7c00019 bfi r0, r9, #0, #1
+0+10 <[^>]+> e7d10010 bfi r0, r0, #0, #18
+0+14 <[^>]+> e7d10890 bfi r0, r0, #17, #1
+0+18 <[^>]+> e7c0001f bfc r0, #0, #1
+0+1c <[^>]+> e7c0001f bfc r0, #0, #1
+0+20 <[^>]+> 17c0001f bfcne r0, #0, #1
+0+24 <[^>]+> e7c0901f bfc r9, #0, #1
+0+28 <[^>]+> e7d1001f bfc r0, #0, #18
+0+2c <[^>]+> e7d1089f bfc r0, #17, #1
+0+30 <[^>]+> e7a00050 sbfx r0, r0, #0, #1
+0+34 <[^>]+> 17a00050 sbfxne r0, r0, #0, #1
+0+38 <[^>]+> e7e00050 ubfx r0, r0, #0, #1
+0+3c <[^>]+> e7a09050 sbfx r9, r0, #0, #1
+0+40 <[^>]+> e7a00059 sbfx r0, r9, #0, #1
+0+44 <[^>]+> e7a008d0 sbfx r0, r0, #17, #1
+0+48 <[^>]+> e7b10050 sbfx r0, r0, #0, #18
+0+4c <[^>]+> e3ff0f30 rbit r0, r0
+0+50 <[^>]+> 13ff0f30 rbitne r0, r0
+0+54 <[^>]+> e3ff9f30 rbit r9, r0
+0+58 <[^>]+> e3ff0f39 rbit r0, r9
+0+5c <[^>]+> e0600090 mls r0, r0, r0, r0
+0+60 <[^>]+> 10600090 mlsne r0, r0, r0, r0
+0+64 <[^>]+> e0690090 mls r9, r0, r0, r0
+0+68 <[^>]+> e0600099 mls r0, r9, r0, r0
+0+6c <[^>]+> e0600990 mls r0, r0, r9, r0
+0+70 <[^>]+> e0609090 mls r0, r0, r0, r9
+0+74 <[^>]+> e3000000 movw r0, #0 ; 0x0
+0+78 <[^>]+> e3400000 movt r0, #0 ; 0x0
+0+7c <[^>]+> 13000000 movwne r0, #0 ; 0x0
+0+80 <[^>]+> e3009000 movw r9, #0 ; 0x0
+0+84 <[^>]+> e3000999 movw r0, #2457 ; 0x999
+0+88 <[^>]+> e3090000 movw r0, #36864 ; 0x9000
+0+8c <[^>]+> e0f900b0 ldrht r0, \[r9\]
+0+90 <[^>]+> e0f900f0 ldrsht r0, \[r9\]
+0+94 <[^>]+> e0f900d0 ldrsbt r0, \[r9\]
+0+98 <[^>]+> e0e900b0 strht r0, \[r9\]
+0+9c <[^>]+> 10f900b0 ldrneht r0, \[r9\]
+0+a0 <[^>]+> e0b090b9 ldrht r9, \[r0\], r9
+0+a4 <[^>]+> e03090b9 ldrht r9, \[r0\], -r9
+0+a8 <[^>]+> e0f099b9 ldrht r9, \[r0\], #153
+0+ac <[^>]+> e07099b9 ldrht r9, \[r0\], #-153
===================================================================
Index: testsuite/gas/arm/archv6t2.s
--- testsuite/gas/arm/archv6t2.s 1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/arm/archv6t2.s 15 Mar 2005 20:34:35 -0000
@@ -0,0 +1,55 @@
+ .text
+x:
+ bfi r0, r0, #0, #1
+ bfine r0, r0, #0, #1
+
+ bfi r9, r0, #0, #1
+ bfi r0, r9, #0, #1
+ bfi r0, r0, #0, #18
+ bfi r0, r0, #17, #1
+
+ bfi r0, #0, #0, #1
+ bfc r0, #0, #1
+ bfcne r0, #0, #1
+ bfc r9, #0, #1
+ bfc r0, #0, #18
+ bfc r0, #17, #1
+
+ sbfx r0, r0, #0, #1
+ sbfxne r0, r0, #0, #1
+ ubfx r0, r0, #0, #1
+ sbfx r9, r0, #0, #1
+ sbfx r0, r9, #0, #1
+ sbfx r0, r0, #17, #1
+ sbfx r0, r0, #0, #18
+
+ rbit r0, r0
+ rbitne r0, r0
+ rbit r9, r0
+ rbit r0, r9
+
+ mls r0, r0, r0, r0
+ mlsne r0, r0, r0, r0
+ mls r9, r0, r0, r0
+ mls r0, r9, r0, r0
+ mls r0, r0, r9, r0
+ mls r0, r0, r0, r9
+
+ movw r0, #0
+ movt r0, #0
+ movwne r0, #0
+ movw r9, #0
+ movw r0, #0x0999
+ movw r0, #0x9000
+
+ @ for these, we must avoid write-back warnings
+ ldrht r0, [r9]
+ ldrsht r0, [r9]
+ ldrsbt r0, [r9]
+ strht r0, [r9]
+ ldrneht r0, [r9]
+
+ ldrht r9, [r0], r9
+ ldrht r9, [r0], -r9
+ ldrht r9, [r0], #0x99
+ ldrht r9, [r0], #-0x99
===================================================================
Index: testsuite/gas/arm/arm.exp
--- testsuite/gas/arm/arm.exp 12 Mar 2005 18:25:47 -0000 1.36
+++ testsuite/gas/arm/arm.exp 15 Mar 2005 20:34:35 -0000
@@ -49,6 +49,7 @@ if {[istarget *arm*-*-*] || [istarget "x
run_dump_test "reg-alias"
run_dump_test "maverick"
run_dump_test "archv6"
+ run_dump_test "archv6t2"
run_dump_test "thumbv6"
run_dump_test "thumbv6k"
run_dump_test "arch6zk"
@@ -57,6 +58,7 @@ if {[istarget *arm*-*-*] || [istarget "x
run_errors_test "req" "-mcpu=arm7m" ".req errors"
run_errors_test "armv1-bad" "-mcpu=arm7m" "ARM v1 errors"
run_errors_test "r15-bad" "" "Invalid use of r15 errors"
+ run_errors_test "archv6t2-bad" "-march=armv6t2" "Invalid V6T2 instructions"
if {[istarget *-*-*coff] || [istarget *-*-pe] || [istarget *-*-wince] ||
[istarget *-*-*aout*] || [istarget *-*-netbsd] || [istarget *-*-riscix*]} then {
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: ARMv6T2 ARM instructions - assembler support
2005-03-15 20:38 ` Zack Weinberg
@ 2005-03-16 14:30 ` Richard Earnshaw
0 siblings, 0 replies; 5+ messages in thread
From: Richard Earnshaw @ 2005-03-16 14:30 UTC (permalink / raw)
To: Zack Weinberg; +Cc: binutils
On Tue, 2005-03-15 at 20:38, Zack Weinberg wrote:
> I have checked in the appended patch which removes the mls diagnostic
> and revises the basic test the way you suggest. (r9 is used because
> that sets the bits at either end of the register field - similarly for
> 17/18 in bit number fields.) Thanks for reviewing.
Looks great, thanks.
R.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2005-03-16 8:41 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-03-14 23:22 ARMv6T2 ARM instructions - assembler support Zack Weinberg
2005-03-15 3:51 ` Zack Weinberg
2005-03-15 10:07 ` Richard Earnshaw
2005-03-15 20:38 ` Zack Weinberg
2005-03-16 14:30 ` Richard Earnshaw
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).