@@ -5273,7 +5273,28 @@ static struct group_reloc_table_entry group_reloc_table[] =
52735273 BFD_RELOC_ARM_ALU_SB_G2, /* ALU */
52745274 BFD_RELOC_ARM_LDR_SB_G2, /* LDR */
52755275 BFD_RELOC_ARM_LDRS_SB_G2, /* LDRS */
5276- BFD_RELOC_ARM_LDC_SB_G2 } }; /* LDC */
5276+ BFD_RELOC_ARM_LDC_SB_G2 }, /* LDC */
5277+ /* Absolute thumb alu relocations. */
5278+ { "lower0_7",
5279+ BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC,/* ALU. */
5280+ 0, /* LDR. */
5281+ 0, /* LDRS. */
5282+ 0 }, /* LDC. */
5283+ { "lower8_15",
5284+ BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC,/* ALU. */
5285+ 0, /* LDR. */
5286+ 0, /* LDRS. */
5287+ 0 }, /* LDC. */
5288+ { "upper0_7",
5289+ BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC,/* ALU. */
5290+ 0, /* LDR. */
5291+ 0, /* LDRS. */
5292+ 0 }, /* LDC. */
5293+ { "upper8_15",
5294+ BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC,/* ALU. */
5295+ 0, /* LDR. */
5296+ 0, /* LDRS. */
5297+ 0 } }; /* LDC. */
52775298
52785299/* Given the address of a pointer pointing to the textual name of a group
52795300 relocation as may appear in assembler source, attempt to find its details
@@ -10394,7 +10415,9 @@ do_t_add_sub (void)
1039410415 {
1039510416 inst.instruction = THUMB_OP16(opcode);
1039610417 inst.instruction |= (Rd << 4) | Rs;
10397- inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
10418+ if (inst.reloc.type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
10419+ || inst.reloc.type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
10420+ inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
1039810421 if (inst.size_req != 2)
1039910422 inst.relax = opcode;
1040010423 }
@@ -11745,9 +11768,13 @@ do_t_mov_cmp (void)
1174511768 inst.instruction = THUMB_OP16 (opcode);
1174611769 inst.instruction |= Rn << 8;
1174711770 if (inst.size_req == 2)
11748- inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
11771+ {
11772+ if (inst.reloc.type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
11773+ || inst.reloc.type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
11774+ inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
11775+ }
1174911776 else
11750- inst.relax = opcode;
11777+ inst.relax = opcode;
1175111778 }
1175211779 else
1175311780 {
@@ -18608,7 +18635,7 @@ static const struct asm_opcode insns[] =
1860818635 CL("cmnp", 170f000, 2, (RR, SH), cmp),
1860918636
1861018637 tCE("mov", 1a00000, _mov, 2, (RR, SH), mov, t_mov_cmp),
18611- tC3("movs", 1b00000, _movs, 2, (RR, SH), mov, t_mov_cmp),
18638+ tC3("movs", 1b00000, _movs, 2, (RR, SHG), mov, t_mov_cmp),
1861218639 tCE("mvn", 1e00000, _mvn, 2, (RR, SH), mov, t_mvn_tst),
1861318640 tC3("mvns", 1f00000, _mvns, 2, (RR, SH), mov, t_mvn_tst),
1861418641
@@ -23242,6 +23269,68 @@ md_apply_fix (fixS * fixP,
2324223269 }
2324323270 return;
2324423271
23272+ case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
23273+ case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
23274+ case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
23275+ case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
23276+ gas_assert (!fixP->fx_done);
23277+ {
23278+ bfd_vma insn;
23279+ bfd_boolean is_mov;
23280+ bfd_vma encoded_addend = value;
23281+
23282+ /* Check that addend can be encoded in instruction. */
23283+ if (!seg->use_rela_p && (value < 0 || value > 255))
23284+ as_bad_where (fixP->fx_file, fixP->fx_line,
23285+ _("the offset 0x%08lX is not representable"),
23286+ (unsigned long) encoded_addend);
23287+
23288+ /* Extract the instruction. */
23289+ insn = md_chars_to_number (buf, THUMB_SIZE);
23290+ is_mov = (insn & 0xf800) == 0x2000;
23291+
23292+ /* Encode insn. */
23293+ if (is_mov)
23294+ {
23295+ if (!seg->use_rela_p)
23296+ insn |= encoded_addend;
23297+ }
23298+ else
23299+ {
23300+ int rd, rs;
23301+
23302+ /* Extract the instruction. */
23303+ /* Encoding is the following
23304+ 0x8000 SUB
23305+ 0x00F0 Rd
23306+ 0x000F Rs
23307+ */
23308+ /* The following conditions must be true :
23309+ - ADD
23310+ - Rd == Rs
23311+ - Rd <= 7
23312+ */
23313+ rd = (insn >> 4) & 0xf;
23314+ rs = insn & 0xf;
23315+ if ((insn & 0x8000) || (rd != rs) || rd > 7)
23316+ as_bad_where (fixP->fx_file, fixP->fx_line,
23317+ _("Unable to process relocation for thumb opcode: %lx"),
23318+ (unsigned long) insn);
23319+
23320+ /* Encode as ADD immediate8 thumb 1 code. */
23321+ insn = 0x3000 | (rd << 8);
23322+
23323+ /* Place the encoded addend into the first 8 bits of the
23324+ instruction. */
23325+ if (!seg->use_rela_p)
23326+ insn |= encoded_addend;
23327+ }
23328+
23329+ /* Update the instruction. */
23330+ md_number_to_chars (buf, insn, THUMB_SIZE);
23331+ }
23332+ break;
23333+
2324523334 case BFD_RELOC_ARM_ALU_PC_G0_NC:
2324623335 case BFD_RELOC_ARM_ALU_PC_G0:
2324723336 case BFD_RELOC_ARM_ALU_PC_G1_NC:
@@ -23579,6 +23668,10 @@ tc_gen_reloc (asection *section, fixS *fixp)
2357923668 case BFD_RELOC_ARM_LDC_SB_G1:
2358023669 case BFD_RELOC_ARM_LDC_SB_G2:
2358123670 case BFD_RELOC_ARM_V4BX:
23671+ case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
23672+ case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
23673+ case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
23674+ case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
2358223675 code = fixp->fx_r_type;
2358323676 break;
2358423677
@@ -23881,6 +23974,12 @@ arm_fix_adjustable (fixS * fixP)
2388123974 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT_PCREL)
2388223975 return FALSE;
2388323976
23977+ /* BFD_RELOC_ARM_THUMB_ALU_ABS_Gx_NC relocations have VERY limited
23978+ offsets, so keep these symbols. */
23979+ if (fixP->fx_r_type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
23980+ && fixP->fx_r_type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
23981+ return FALSE;
23982+
2388423983 return TRUE;
2388523984}
2388623985#endif /* defined (OBJ_ELF) || defined (OBJ_COFF) */
0 commit comments