diff --git a/gas/ChangeLog b/gas/ChangeLog index 6790664019..ce3663d683 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2005-03-15 Zack Weinberg + + * 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. + 2005-03-15 Nick Clifton * NEWS: Add cutoff for changes in 2.16 release. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 3ab5aa1524..5cce0a9a3b 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -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, #. */ +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 . */ @@ -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_archs[] = {"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} diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 4ea866d028..86af7eb244 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2005-03-15 Zack Weinberg + + * 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. + 2005-03-14 Eric Christopher * gas/cfi/cfi-mips-1.d, gas/cfi/cfi-mips-1.s: New dump test. diff --git a/gas/testsuite/gas/arm/archv6t2-bad.l b/gas/testsuite/gas/arm/archv6t2-bad.l new file mode 100644 index 0000000000..e8da4b8aad --- /dev/null +++ b/gas/testsuite/gas/arm/archv6t2-bad.l @@ -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 diff --git a/gas/testsuite/gas/arm/archv6t2-bad.s b/gas/testsuite/gas/arm/archv6t2-bad.s new file mode 100644 index 0000000000..e56886912f --- /dev/null +++ b/gas/testsuite/gas/arm/archv6t2-bad.s @@ -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] diff --git a/gas/testsuite/gas/arm/archv6t2.d b/gas/testsuite/gas/arm/archv6t2.d new file mode 100644 index 0000000000..8e8b0387a3 --- /dev/null +++ b/gas/testsuite/gas/arm/archv6t2.d @@ -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 diff --git a/gas/testsuite/gas/arm/archv6t2.s b/gas/testsuite/gas/arm/archv6t2.s new file mode 100644 index 0000000000..292f11cf5d --- /dev/null +++ b/gas/testsuite/gas/arm/archv6t2.s @@ -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 diff --git a/gas/testsuite/gas/arm/arm.exp b/gas/testsuite/gas/arm/arm.exp index a84c80b093..4ea6454318 100644 --- a/gas/testsuite/gas/arm/arm.exp +++ b/gas/testsuite/gas/arm/arm.exp @@ -49,6 +49,7 @@ if {[istarget *arm*-*-*] || [istarget "xscale-*-*"]} then { 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 "xscale-*-*"]} then { 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 {