{
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;
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;
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;
{
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;
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;
{
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;
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)
{
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;
{
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 ();
}
}
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;
# 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