From 44affbdcf44baebc9158bf631573c6335a43845d Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Thu, 14 Jun 2007 22:06:19 +0000 Subject: [PATCH] 2007-06-14 Paul Brook gas/ * config/tc-arm.c (do_t_mov_cmp): Handle shift by register and narrow shift by immediate. gas/testsuite/ * gas/arm/thumb32.s: Add tests for shift instructions. * gas/arm/thumb32.d: Ditto. --- gas/ChangeLog | 5 +++ gas/config/tc-arm.c | 93 +++++++++++++++++++++++++++++++++++++++-- gas/testsuite/ChangeLog | 5 +++ gas/testsuite/gas/arm/thumb32.d | 29 +++++++++++++ gas/testsuite/gas/arm/thumb32.s | 14 +++++++ 5 files changed, 143 insertions(+), 3 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index dd470e75cb..a418e70488 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2007-06-14 Paul Brook + + * config/tc-arm.c (do_t_mov_cmp): Handle shift by register and + narrow shift by immediate. + 2007-06-14 H.J. Lu * Makefile.am (ACLOCAL_AMFLAGS): Add -I ../config -I ../bfd. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 339cab5db8..54e8483418 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -9544,11 +9544,98 @@ do_t_mov_cmp (void) inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE; } } + else if (inst.operands[1].shifted && inst.operands[1].immisreg + && (inst.instruction == T_MNEM_mov + || inst.instruction == T_MNEM_movs)) + { + /* Register shifts are encoded as separate shift instructions. */ + bfd_boolean flags = (inst.instruction == T_MNEM_movs); + + if (current_it_mask) + narrow = !flags; + else + narrow = flags; + + if (inst.size_req == 4) + narrow = FALSE; + + if (!low_regs || inst.operands[1].imm > 7) + narrow = FALSE; + + if (inst.operands[0].reg != inst.operands[1].reg) + narrow = FALSE; + + switch (inst.operands[1].shift_kind) + { + case SHIFT_LSL: + opcode = narrow ? T_OPCODE_LSL_R : THUMB_OP32 (T_MNEM_lsl); + break; + case SHIFT_ASR: + opcode = narrow ? T_OPCODE_ASR_R : THUMB_OP32 (T_MNEM_asr); + break; + case SHIFT_LSR: + opcode = narrow ? T_OPCODE_LSR_R : THUMB_OP32 (T_MNEM_lsr); + break; + case SHIFT_ROR: + opcode = narrow ? T_OPCODE_ROR_R : THUMB_OP32 (T_MNEM_ror); + break; + default: + abort(); + } + + inst.instruction = opcode; + if (narrow) + { + inst.instruction |= inst.operands[0].reg; + inst.instruction |= inst.operands[1].imm << 3; + } + else + { + if (flags) + inst.instruction |= CONDS_BIT; + + inst.instruction |= inst.operands[0].reg << 8; + inst.instruction |= inst.operands[1].reg << 16; + inst.instruction |= inst.operands[1].imm; + } + } else if (!narrow) { - inst.instruction = THUMB_OP32 (inst.instruction); - inst.instruction |= inst.operands[0].reg << r0off; - encode_thumb32_shifted_operand (1); + /* Some mov with immediate shift have narrow variants. + Register shifts are handled above. */ + if (low_regs && inst.operands[1].shifted + && (inst.instruction == T_MNEM_mov + || inst.instruction == T_MNEM_movs)) + { + if (current_it_mask) + narrow = (inst.instruction == T_MNEM_mov); + else + narrow = (inst.instruction == T_MNEM_movs); + } + + if (narrow) + { + switch (inst.operands[1].shift_kind) + { + case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break; + case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break; + case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break; + default: narrow = FALSE; break; + } + } + + if (narrow) + { + inst.instruction |= inst.operands[0].reg; + inst.instruction |= inst.operands[1].reg << 3; + inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT; + } + else + { + inst.instruction = THUMB_OP32 (inst.instruction); + inst.instruction |= inst.operands[0].reg << r0off; + encode_thumb32_shifted_operand (1); + } } else switch (inst.instruction) diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 2803af8eab..e6ea7aeaf0 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-06-14 Paul Brook + + * gas/arm/thumb32.s: Add tests for shift instructions. + * gas/arm/thumb32.d: Ditto. + 2007-06-06 Paul Brook * gas/arm/thumb.d: Update expected output. diff --git a/gas/testsuite/gas/arm/thumb32.d b/gas/testsuite/gas/arm/thumb32.d index 5bb76a5392..0d96818858 100644 --- a/gas/testsuite/gas/arm/thumb32.d +++ b/gas/testsuite/gas/arm/thumb32.d @@ -1001,3 +1001,32 @@ Disassembly of section .text: 0[0-9a-f]+ <[^>]+> f935 1b30 ldrsh.w r1, \[r5\], #48 0[0-9a-f]+ <[^>]+> f935 1930 ldrsh.w r1, \[r5\], #-48 0[0-9a-f]+ <[^>]+> f935 1009 ldrsh.w r1, \[r5, r9\] +0[0-9a-f]+ <[^>]+> 00a1 lsls r1, r4, #2 +0[0-9a-f]+ <[^>]+> ea5f 0389 movs.w r3, r9, lsl #2 +0[0-9a-f]+ <[^>]+> fa12 f103 lsls.w r1, r2, r3 +0[0-9a-f]+ <[^>]+> 4099 lsls r1, r3 +0[0-9a-f]+ <[^>]+> fa11 f109 lsls.w r1, r1, r9 +0[0-9a-f]+ <[^>]+> fa02 f103 lsl.w r1, r2, r3 +0[0-9a-f]+ <[^>]+> fa01 f103 lsl.w r1, r1, r3 +0[0-9a-f]+ <[^>]+> 08a1 lsrs r1, r4, #2 +0[0-9a-f]+ <[^>]+> ea5f 0399 movs.w r3, r9, lsr #2 +0[0-9a-f]+ <[^>]+> fa32 f103 lsrs.w r1, r2, r3 +0[0-9a-f]+ <[^>]+> 40d9 lsrs r1, r3 +0[0-9a-f]+ <[^>]+> fa31 f109 lsrs.w r1, r1, r9 +0[0-9a-f]+ <[^>]+> fa22 f103 lsr.w r1, r2, r3 +0[0-9a-f]+ <[^>]+> fa21 f103 lsr.w r1, r1, r3 +0[0-9a-f]+ <[^>]+> 10a1 asrs r1, r4, #2 +0[0-9a-f]+ <[^>]+> ea5f 03a9 movs.w r3, r9, asr #2 +0[0-9a-f]+ <[^>]+> fa52 f103 asrs.w r1, r2, r3 +0[0-9a-f]+ <[^>]+> 4119 asrs r1, r3 +0[0-9a-f]+ <[^>]+> fa51 f109 asrs.w r1, r1, r9 +0[0-9a-f]+ <[^>]+> fa42 f103 asr.w r1, r2, r3 +0[0-9a-f]+ <[^>]+> fa41 f103 asr.w r1, r1, r3 +0[0-9a-f]+ <[^>]+> ea5f 01b4 movs.w r1, r4, ror #2 +0[0-9a-f]+ <[^>]+> ea5f 03b9 movs.w r3, r9, ror #2 +0[0-9a-f]+ <[^>]+> fa72 f103 rors.w r1, r2, r3 +0[0-9a-f]+ <[^>]+> 41d9 rors r1, r3 +0[0-9a-f]+ <[^>]+> fa71 f109 rors.w r1, r1, r9 +0[0-9a-f]+ <[^>]+> fa62 f103 ror.w r1, r2, r3 +0[0-9a-f]+ <[^>]+> fa61 f103 ror.w r1, r1, r3 +0[0-9a-f]+ <[^>]+> bf00 nop diff --git a/gas/testsuite/gas/arm/thumb32.s b/gas/testsuite/gas/arm/thumb32.s index 4f602df35d..697dfd240f 100644 --- a/gas/testsuite/gas/arm/thumb32.s +++ b/gas/testsuite/gas/arm/thumb32.s @@ -803,3 +803,17 @@ srs: ldaddr sb ldaddr h ldaddr sh + .macro movshift op s="s" + movs r1, r4, \op #2 + movs r3, r9, \op #2 + movs r1, r2, \op r3 + movs r1, r1, \op r3 + movs r1, r1, \op r9 + mov r1, r2, \op r3 + mov r1, r1, \op r3 + .endm + movshift lsl + movshift lsr + movshift asr + movshift ror + nop -- 2.11.0