From 3d3889971085bdb9017e31881c2bfc7600e44c55 Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Mon, 15 Aug 2005 19:19:55 +0000 Subject: [PATCH] 2005-08-15 Paul Brook gas/ * config/tc-arm.c (do_t_mov_cmp): Fix encoding of i16-bit conditional instructions. (do_t_mvn_tst, do_t_neg, do_t_shift): Ditto. gas/testsuite/ * gas/arm/thumb2_it.s: Add more instruction variants. * gas/arm/thumb2_it.d: Ditto. --- gas/ChangeLog | 6 ++ gas/config/tc-arm.c | 125 ++++++++++++++++++++---------- gas/testsuite/ChangeLog | 5 ++ gas/testsuite/gas/arm/thumb2_it.d | 68 ++++++++++++---- gas/testsuite/gas/arm/thumb2_it.s | 40 ++++++++++ 5 files changed, 187 insertions(+), 57 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index f6ca310d8d9..a17d6515cc9 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2005-08-15 Paul Brook + + * config/tc-arm.c (do_t_mov_cmp): Fix encoding of i16-bit conditional + instructions. + (do_t_mvn_tst, do_t_neg, do_t_shift): Ditto. + 2005-08-15 Daniel Jacobowitz * config/tc-ppc.c (parse_cpu): Add -me300 support. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 7cd3db4f390..fd95edb283e 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -6696,6 +6696,18 @@ do_t_mov_cmp (void) { int r0off = (inst.instruction == T_MNEM_mov || inst.instruction == T_MNEM_movs) ? 8 : 16; + bfd_boolean narrow; + bfd_boolean low_regs; + + low_regs = (inst.operands[0].reg <= 7 && inst.operands[1].reg <= 7); + if (current_it_mask) + narrow = inst.instruction != T_MNEM_movs; + else + narrow = inst.instruction != T_MNEM_movs || low_regs; + if (inst.size_req == 4 + || inst.operands[1].shifted) + narrow = FALSE; + if (!inst.operands[1].isreg) { /* For an immediate, we always generate a 32-bit opcode; @@ -6705,10 +6717,7 @@ do_t_mov_cmp (void) inst.instruction |= inst.operands[0].reg << r0off; inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE; } - else if (inst.size_req == 4 - || inst.operands[1].shifted - || (inst.instruction == T_MNEM_movs - && (inst.operands[0].reg > 7 || inst.operands[1].reg > 7))) + else if (!narrow) { inst.instruction = THUMB_OP32 (inst.instruction); inst.instruction |= inst.operands[0].reg << r0off; @@ -6733,7 +6742,7 @@ do_t_mov_cmp (void) break; case T_MNEM_cmp: - if (inst.operands[0].reg <= 7 && inst.operands[1].reg <= 7) + if (low_regs) { inst.instruction = T_OPCODE_CMP_LR; inst.instruction |= inst.operands[0].reg; @@ -6801,6 +6810,20 @@ do_t_mvn_tst (void) { int r0off = (inst.instruction == T_MNEM_mvn || inst.instruction == T_MNEM_mvns) ? 8 : 16; + bfd_boolean narrow; + + if (inst.size_req == 4 + || inst.instruction > 0xffff + || inst.operands[1].shifted + || inst.operands[0].reg > 7 || inst.operands[1].reg > 7) + narrow = FALSE; + else if (inst.instruction == T_MNEM_cmn) + narrow = TRUE; + else if (THUMB_SETS_FLAGS (inst.instruction)) + narrow = (current_it_mask == 0); + else + narrow = (current_it_mask != 0); + if (!inst.operands[1].isreg) { /* For an immediate, we always generate a 32-bit opcode; @@ -6814,12 +6837,7 @@ do_t_mvn_tst (void) else { /* See if we can do this with a 16-bit instruction. */ - if (inst.instruction < 0xffff - && THUMB_SETS_FLAGS (inst.instruction) - && !inst.operands[1].shifted - && inst.operands[0].reg <= 7 - && inst.operands[1].reg <= 7 - && inst.size_req != 4) + if (narrow) { inst.instruction = THUMB_OP16 (inst.instruction); inst.instruction |= inst.operands[0].reg; @@ -6947,9 +6965,18 @@ do_t_neg (void) { if (unified_syntax) { - if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7 - || !THUMB_SETS_FLAGS (inst.instruction) - || inst.size_req == 4) + bfd_boolean narrow; + + if (THUMB_SETS_FLAGS (inst.instruction)) + narrow = (current_it_mask == 0); + else + narrow = (current_it_mask != 0); + if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7) + narrow = FALSE; + if (inst.size_req == 4) + narrow = FALSE; + + if (!narrow) { inst.instruction = THUMB_OP32 (inst.instruction); inst.instruction |= inst.operands[0].reg << 8; @@ -7127,12 +7154,38 @@ do_t_shift (void) if (unified_syntax) { - if (inst.operands[0].reg > 7 - || inst.operands[1].reg > 7 - || !THUMB_SETS_FLAGS (inst.instruction) - || (!inst.operands[2].isreg && inst.instruction == T_MNEM_rors) - || (inst.operands[2].isreg && inst.operands[1].reg != inst.operands[0].reg) - || inst.size_req == 4) + bfd_boolean narrow; + int shift_kind; + + switch (inst.instruction) + { + case T_MNEM_asr: + case T_MNEM_asrs: shift_kind = SHIFT_ASR; break; + case T_MNEM_lsl: + case T_MNEM_lsls: shift_kind = SHIFT_LSL; break; + case T_MNEM_lsr: + case T_MNEM_lsrs: shift_kind = SHIFT_LSR; break; + case T_MNEM_ror: + case T_MNEM_rors: shift_kind = SHIFT_ROR; break; + default: abort (); + } + + if (THUMB_SETS_FLAGS (inst.instruction)) + narrow = (current_it_mask == 0); + else + narrow = (current_it_mask != 0); + if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7) + narrow = FALSE; + if (!inst.operands[2].isreg && shift_kind == SHIFT_ROR) + narrow = FALSE; + if (inst.operands[2].isreg + && (inst.operands[1].reg != inst.operands[0].reg + || inst.operands[2].reg > 7)) + narrow = FALSE; + if (inst.size_req == 4) + narrow = FALSE; + + if (!narrow) { if (inst.operands[2].isreg) { @@ -7144,19 +7197,7 @@ do_t_shift (void) else { inst.operands[1].shifted = 1; - switch (inst.instruction) - { - case T_MNEM_asr: - case T_MNEM_asrs: inst.operands[1].shift_kind = SHIFT_ASR; break; - case T_MNEM_lsl: - case T_MNEM_lsls: inst.operands[1].shift_kind = SHIFT_LSL; break; - case T_MNEM_lsr: - case T_MNEM_lsrs: inst.operands[1].shift_kind = SHIFT_LSR; break; - case T_MNEM_ror: - case T_MNEM_rors: inst.operands[1].shift_kind = SHIFT_ROR; break; - default: abort (); - } - + inst.operands[1].shift_kind = shift_kind; inst.instruction = THUMB_OP32 (THUMB_SETS_FLAGS (inst.instruction) ? T_MNEM_movs : T_MNEM_mov); inst.instruction |= inst.operands[0].reg << 8; @@ -7169,12 +7210,12 @@ do_t_shift (void) { if (inst.operands[2].isreg) { - switch (inst.instruction) + switch (shift_kind) { - case T_MNEM_asrs: inst.instruction = T_OPCODE_ASR_R; break; - case T_MNEM_lsls: inst.instruction = T_OPCODE_LSL_R; break; - case T_MNEM_lsrs: inst.instruction = T_OPCODE_LSR_R; break; - case T_MNEM_rors: inst.instruction = T_OPCODE_ROR_R; break; + case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_R; break; + case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_R; break; + case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_R; break; + case SHIFT_ROR: inst.instruction = T_OPCODE_ROR_R; break; default: abort (); } @@ -7183,11 +7224,11 @@ do_t_shift (void) } else { - switch (inst.instruction) + switch (shift_kind) { - case T_MNEM_asrs: inst.instruction = T_OPCODE_ASR_I; break; - case T_MNEM_lsls: inst.instruction = T_OPCODE_LSL_I; break; - case T_MNEM_lsrs: inst.instruction = T_OPCODE_LSR_I; break; + case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break; + case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break; + case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break; default: abort (); } inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT; diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 7773f20e83c..d5860c92c01 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-08-15 Paul Brook + + * gas/arm/thumb2_it.s: Add more instruction variants. + * gas/arm/thumb2_it.d: Ditto. + 2005-08-12 Martin Schwidefsky * gas/testsuite/gas/s390/s390.exp: Reorganize gas testsuite for s390 diff --git a/gas/testsuite/gas/arm/thumb2_it.d b/gas/testsuite/gas/arm/thumb2_it.d index 69df8157f32..30a390bbb0a 100644 --- a/gas/testsuite/gas/arm/thumb2_it.d +++ b/gas/testsuite/gas/arm/thumb2_it.d @@ -1,24 +1,62 @@ # name: Mixed 16 and 32-bit Thumb conditional instructions # as: -march=armv6kt2 # objdump: -dr --prefix-addresses --show-raw-insn +# Many of these patterns use "(eq|s)". These should be changed to just "eq" +# once the disassembler is fixed. Likewise for "(eq)?" .*: +file format .*arm.* Disassembly of section .text: 0+000 <[^>]+> bf05 ittet eq -0+002 <[^>]+> 1880 add.* r0, r0, r2 -0+004 <[^>]+> 4440 add.* r0, r8 -0+006 <[^>]+> 1888 add.* r0, r1, r2 -0+008 <[^>]+> eb11 0002 adds.* r0, r1, r2 -0+00c <[^>]+> 4410 add.* r0, r2 -0+00e <[^>]+> 4440 add.* r0, r8 -0+010 <[^>]+> 1880 adds.* r0, r0, r2 -0+012 <[^>]+> eb10 0008 adds.* r0, r0, r8 -0+016 <[^>]+> 1888 adds.* r0, r1, r2 +0+002 <[^>]+> 1880 add(eq|s) r0, r0, r2 +0+004 <[^>]+> 4440 add(eq)? r0, r8 +0+006 <[^>]+> 1888 add(ne|s) r0, r1, r2 +0+008 <[^>]+> eb11 0002 adds(eq)?.w r0, r1, r2 +0+00c <[^>]+> 4410 add r0, r2 +0+00e <[^>]+> 4440 add r0, r8 +0+010 <[^>]+> 1880 adds r0, r0, r2 +0+012 <[^>]+> eb10 0008 adds.w r0, r0, r8 +0+016 <[^>]+> 1888 adds r0, r1, r2 0+018 <[^>]+> bf0a itet eq -0+01a <[^>]+> 4310 orr.* r0, r2 -0+01c <[^>]+> ea40 0008 orr.* r0, r0, r8 -0+020 <[^>]+> ea50 0002 orrs.* r0, r0, r2 -0+024 <[^>]+> ea40 0002 orr.* r0, r0, r2 -0+028 <[^>]+> ea40 0008 orr.* r0, r0, r8 -0+02c <[^>]+> 4310 orrs.* r0, r2 +0+01a <[^>]+> 4310 orr(eq|s) r0, r2 +0+01c <[^>]+> ea40 0008 orr(ne)?.w r0, r0, r8 +0+020 <[^>]+> ea50 0002 orrs(eq)?.w r0, r0, r2 +0+024 <[^>]+> ea40 0002 orr.w r0, r0, r2 +0+028 <[^>]+> ea40 0008 orr.w r0, r0, r8 +0+02c <[^>]+> 4310 orrs r0, r2 +0+02e <[^>]+> bf01 itttt eq +0+030 <[^>]+> 4090 lsl(eq|s) r0, r2 +0+032 <[^>]+> fa00 f008 lsl(eq)?.w r0, r0, r8 +0+036 <[^>]+> fa01 f002 lsl(eq)?.w r0, r1, r2 +0+03a <[^>]+> fa10 f002 lsls(eq)?.w r0, r0, r2 +0+03e <[^>]+> bf02 ittt eq +0+040 <[^>]+> 0048 lsl(eq|s) r0, r1, #1 +0+042 <[^>]+> ea4f 0048 mov(eq)?.w r0, r8, lsl #1 +0+046 <[^>]+> ea5f 0040 movs(eq)?.w r0, r0, lsl #1 +0+04a <[^>]+> fa00 f002 lsl.w r0, r0, r2 +0+04e <[^>]+> 4090 lsls r0, r2 +0+050 <[^>]+> ea4f 0041 mov.w r0, r1, lsl #1 +0+054 <[^>]+> 0048 lsls r0, r1, #1 +0+056 <[^>]+> bf01 itttt eq +0+058 <[^>]+> 4288 cmp(eq)? r0, r1 +0+05a <[^>]+> 4540 cmp(eq)? r0, r8 +0+05c <[^>]+> 4608 mov(eq)? r0, r1 +0+05e <[^>]+> ea5f 0001 movs(eq)?.w r0, r1 +0+062 <[^>]+> bf08 it eq +0+064 <[^>]+> 4640 mov(eq)? r0, r8 +0+066 <[^>]+> 4608 mov(eq)? r0, r1 +0+068 <[^>]+> 1c08 adds r0, r1, #0 +0+06a <[^>]+> ea5f 0008 movs.w r0, r8 +0+06e <[^>]+> bf01 itttt eq +0+070 <[^>]+> 43c8 mvn(eq|s) r0, r1 +0+072 <[^>]+> ea6f 0008 mvn(eq)?.w r0, r8 +0+076 <[^>]+> ea7f 0001 mvns(eq)?.w r0, r1 +0+07a <[^>]+> 42c8 cmn(eq)? r0, r1 +0+07c <[^>]+> ea6f 0001 mvn.w r0, r1 +0+080 <[^>]+> 43c8 mvns r0, r1 +0+082 <[^>]+> bf02 ittt eq +0+084 <[^>]+> 4248 neg(eq|s) r0, r1 +0+086 <[^>]+> f1c8 0000 rsb(eq)? r0, r8, #0 ; 0x0 +0+08a <[^>]+> f1d1 0000 rsbs(eq)? r0, r1, #0 ; 0x0 +0+08e <[^>]+> f1c1 0000 rsb r0, r1, #0 ; 0x0 +0+092 <[^>]+> 4248 negs r0, r1 diff --git a/gas/testsuite/gas/arm/thumb2_it.s b/gas/testsuite/gas/arm/thumb2_it.s index 2b487573e27..c12abb6242f 100644 --- a/gas/testsuite/gas/arm/thumb2_it.s +++ b/gas/testsuite/gas/arm/thumb2_it.s @@ -22,3 +22,43 @@ foo: orr r0, r0, r8 orrs r0, r0, r2 + itttt eq + lsleq r0, r0, r2 + lsleq r0, r0, r8 + lsleq r0, r1, r2 + lslseq r0, r0, r2 + ittt eq + lsleq r0, r1, #1 + lsleq r0, r8, #1 + lslseq r0, r0, #1 + lsl r0, r0, r2 + lsls r0, r0, r2 + lsl r0, r1, #1 + lsls r0, r1, #1 + + itttt eq + cmpeq r0, r1 + cmpeq r0, r8 + moveq r0, r1 + movseq r0, r1 + it eq + moveq r0, r8 + mov r0, r1 + movs r0, r1 + movs r0, r8 + + itttt eq + mvneq r0, r1 + mvneq r0, r8 + mvnseq r0, r1 + cmneq r0, r1 + mvn r0, r1 + mvns r0, r1 + + ittt eq + negeq r0, r1 + negeq r0, r8 + negseq r0, r1 + neg r0, r1 + negs r0, r1 + -- 2.30.2