From b6895b4f375bfb1de5a8d33b3af600c5d92314d8 Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Thu, 11 May 2006 15:17:34 +0000 Subject: [PATCH] 2006-05-11 Paul Brook bfd/ * elf32-arm.c (elf32_arm_reloc_map): Add MOVW and MOVT relocs. (elf32_arm_final_link_relocate): Handle MOVW and MOVT relocs. (elf32_arm_gc_sweep_hook, elf32_arm_check_relocs): Ditto. * reloc.c: Ditto. * bfd-in2.h: Regenerate. * libbfd.h: Regenerate. * libcoff.h: Regenerate. gas/ * config/tc-arm.c (parse_half): New function. (operand_parse_code): Remove OP_Iffff. Add OP_HALF. (parse_operands): Ditto. (do_mov16): Reject invalid relocations. (do_t_mov16): Ditto. Use Thumb reloc numbers. (insns): Replace Iffff with HALF. (md_apply_fix): Add MOVW and MOVT relocs. (tc_gen_reloc): Ditto. * doc/c-arm.texi: Document relocation operators ld/testsuite/ * ld-arm/arm-elf.exp: Add arm-movwt. * ld-arm/arm-movwt.d: New test. * ld-arm/arm-movwt.s: New test. * ld-arm/arm.ld: Add .far. --- bfd/ChangeLog | 10 ++ bfd/bfd-in2.h | 10 ++ bfd/elf32-arm.c | 101 +++++++++++++++++-- bfd/libbfd.h | 8 ++ bfd/reloc.c | 18 ++++ gas/ChangeLog | 12 +++ gas/config/tc-arm.c | 166 +++++++++++++++++++++++++++++--- gas/doc/c-arm.texi | 40 ++++++++ ld/testsuite/ChangeLog | 7 ++ ld/testsuite/ld-arm/arm-elf.exp | 3 + ld/testsuite/ld-arm/arm-movwt.d | 39 ++++++++ ld/testsuite/ld-arm/arm-movwt.s | 44 +++++++++ ld/testsuite/ld-arm/arm.ld | 2 + 13 files changed, 443 insertions(+), 17 deletions(-) create mode 100644 ld/testsuite/ld-arm/arm-movwt.d create mode 100644 ld/testsuite/ld-arm/arm-movwt.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a95fd4f5bb9..9f9ba30bcac 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2006-05-11 Paul Brook + + * elf32-arm.c (elf32_arm_reloc_map): Add MOVW and MOVT relocs. + (elf32_arm_final_link_relocate): Handle MOVW and MOVT relocs. + (elf32_arm_gc_sweep_hook, elf32_arm_check_relocs): Ditto. + * reloc.c: Ditto. + * bfd-in2.h: Regenerate. + * libbfd.h: Regenerate. + * libcoff.h: Regenerate. + 2006-05-11 Mike Bland * elf.c (_bfd_elf_init_private_section_data): Don't change diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 94118cc5d1a..5ba74d28388 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2897,6 +2897,16 @@ pc-relative or some form of GOT-indirect relocation. */ /* 31-bit PC relative address. */ BFD_RELOC_ARM_PREL31, +/* Low and High halfword relocations for MOVW and MOVT instructions. */ + BFD_RELOC_ARM_MOVW, + BFD_RELOC_ARM_MOVT, + BFD_RELOC_ARM_MOVW_PCREL, + BFD_RELOC_ARM_MOVT_PCREL, + BFD_RELOC_ARM_THUMB_MOVW, + BFD_RELOC_ARM_THUMB_MOVT, + BFD_RELOC_ARM_THUMB_MOVW_PCREL, + BFD_RELOC_ARM_THUMB_MOVT_PCREL, + /* Relocations for setting up GOTs and PLTs for shared libraries. */ BFD_RELOC_ARM_JUMP_SLOT, BFD_RELOC_ARM_GLOB_DAT, diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 3b4152aab8f..e0a5abece32 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -1366,6 +1366,14 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] = {BFD_RELOC_ARM_TLS_LE32, R_ARM_TLS_LE32}, {BFD_RELOC_VTABLE_INHERIT, R_ARM_GNU_VTINHERIT}, {BFD_RELOC_VTABLE_ENTRY, R_ARM_GNU_VTENTRY}, + {BFD_RELOC_ARM_MOVW, R_ARM_MOVW_ABS_NC}, + {BFD_RELOC_ARM_MOVT, R_ARM_MOVT_ABS}, + {BFD_RELOC_ARM_MOVW_PCREL, R_ARM_MOVW_PREL_NC}, + {BFD_RELOC_ARM_MOVT_PCREL, R_ARM_MOVT_PREL}, + {BFD_RELOC_ARM_THUMB_MOVW, R_ARM_THM_MOVW_ABS_NC}, + {BFD_RELOC_ARM_THUMB_MOVT, R_ARM_THM_MOVT_ABS}, + {BFD_RELOC_ARM_THUMB_MOVW_PCREL, R_ARM_THM_MOVW_PREL_NC}, + {BFD_RELOC_ARM_THUMB_MOVT_PCREL, R_ARM_THM_MOVT_PREL}, }; static reloc_howto_type * @@ -4080,6 +4088,76 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, } return bfd_reloc_ok; + case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVT_ABS: + case R_ARM_MOVW_PREL_NC: + case R_ARM_MOVT_PREL: + { + bfd_vma insn = bfd_get_32 (input_bfd, hit_data); + + if (globals->use_rel) + { + addend = ((insn >> 4) & 0xf000) | (insn & 0xfff); + signed_addend = (addend ^ 0x10000) - 0x10000; + } + value += signed_addend; + if (sym_flags == STT_ARM_TFUNC) + value |= 1; + + if (r_type == R_ARM_MOVW_PREL_NC || r_type == R_ARM_MOVT_PREL) + value -= (input_section->output_section->vma + + input_section->output_offset + rel->r_offset); + + if (r_type == R_ARM_MOVT_ABS || r_type == R_ARM_MOVT_PREL) + value >>= 16; + + insn &= 0xfff0f000; + insn |= value & 0xfff; + insn |= (value & 0xf000) << 4; + bfd_put_32 (input_bfd, insn, hit_data); + } + return bfd_reloc_ok; + + case R_ARM_THM_MOVW_ABS_NC: + case R_ARM_THM_MOVT_ABS: + case R_ARM_THM_MOVW_PREL_NC: + case R_ARM_THM_MOVT_PREL: + { + bfd_vma insn; + + insn = bfd_get_16 (input_bfd, hit_data) << 16; + insn |= bfd_get_16 (input_bfd, hit_data + 2); + + if (globals->use_rel) + { + addend = ((insn >> 4) & 0xf000) + | ((insn >> 15) & 0x0800) + | ((insn >> 4) & 0x0700) + | (insn & 0x00ff); + signed_addend = (addend ^ 0x10000) - 0x10000; + } + value += signed_addend; + if (sym_flags == STT_ARM_TFUNC) + value |= 1; + + if (r_type == R_ARM_THM_MOVW_PREL_NC || r_type == R_ARM_THM_MOVT_PREL) + value -= (input_section->output_section->vma + + input_section->output_offset + rel->r_offset); + + if (r_type == R_ARM_THM_MOVT_ABS || r_type == R_ARM_THM_MOVT_PREL) + value >>= 16; + + insn &= 0xfbf08f00; + insn |= (value & 0xf000) << 4; + insn |= (value & 0x0800) << 15; + insn |= (value & 0x0700) << 4; + insn |= (value & 0x00ff); + + bfd_put_16 (input_bfd, insn >> 16, hit_data); + bfd_put_16 (input_bfd, insn & 0xffff, hit_data + 2); + } + return bfd_reloc_ok; + default: return bfd_reloc_notsupported; } @@ -5651,6 +5729,14 @@ elf32_arm_gc_sweep_hook (bfd * abfd, case R_ARM_JUMP24: case R_ARM_PREL31: case R_ARM_THM_CALL: + case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVT_ABS: + case R_ARM_MOVW_PREL_NC: + case R_ARM_MOVT_PREL: + case R_ARM_THM_MOVW_ABS_NC: + case R_ARM_THM_MOVT_ABS: + case R_ARM_THM_MOVW_PREL_NC: + case R_ARM_THM_MOVT_PREL: /* Should the interworking branches be here also? */ if (h != NULL) @@ -5861,6 +5947,14 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_ARM_JUMP24: case R_ARM_PREL31: case R_ARM_THM_CALL: + case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVT_ABS: + case R_ARM_MOVW_PREL_NC: + case R_ARM_MOVT_PREL: + case R_ARM_THM_MOVW_ABS_NC: + case R_ARM_THM_MOVT_ABS: + case R_ARM_THM_MOVW_PREL_NC: + case R_ARM_THM_MOVT_PREL: /* Should the interworking branches be listed here? */ if (h != NULL) { @@ -5877,12 +5971,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info, refers to is in a different object. We can't tell for sure yet, because something later might force the symbol local. */ - if (r_type == R_ARM_PC24 - || r_type == R_ARM_CALL - || r_type == R_ARM_JUMP24 - || r_type == R_ARM_PREL31 - || r_type == R_ARM_PLT32 - || r_type == R_ARM_THM_CALL) + if (r_type != R_ARM_ABS32 && r_type != R_ARM_REL32) h->needs_plt = 1; /* If we create a PLT entry, this relocation will reference diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 6cbef4809f4..34b0f4f45d0 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1208,6 +1208,14 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_ARM_SBREL32", "BFD_RELOC_ARM_TARGET2", "BFD_RELOC_ARM_PREL31", + "BFD_RELOC_ARM_MOVW", + "BFD_RELOC_ARM_MOVT", + "BFD_RELOC_ARM_MOVW_PCREL", + "BFD_RELOC_ARM_MOVT_PCREL", + "BFD_RELOC_ARM_THUMB_MOVW", + "BFD_RELOC_ARM_THUMB_MOVT", + "BFD_RELOC_ARM_THUMB_MOVW_PCREL", + "BFD_RELOC_ARM_THUMB_MOVT_PCREL", "BFD_RELOC_ARM_JUMP_SLOT", "BFD_RELOC_ARM_GLOB_DAT", "BFD_RELOC_ARM_GOT32", diff --git a/bfd/reloc.c b/bfd/reloc.c index f1d09a5ab07..6adc7fbdc62 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2701,6 +2701,24 @@ ENUM BFD_RELOC_ARM_PREL31 ENUMDOC 31-bit PC relative address. +ENUM + BFD_RELOC_ARM_MOVW +ENUMX + BFD_RELOC_ARM_MOVT +ENUMX + BFD_RELOC_ARM_MOVW_PCREL +ENUMX + BFD_RELOC_ARM_MOVT_PCREL +ENUMX + BFD_RELOC_ARM_THUMB_MOVW +ENUMX + BFD_RELOC_ARM_THUMB_MOVT +ENUMX + BFD_RELOC_ARM_THUMB_MOVW_PCREL +ENUMX + BFD_RELOC_ARM_THUMB_MOVT_PCREL +ENUMDOC + Low and High halfword relocations for MOVW and MOVT instructions. ENUM BFD_RELOC_ARM_JUMP_SLOT diff --git a/gas/ChangeLog b/gas/ChangeLog index 35a8dbedab3..c97bb65d59e 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,15 @@ +2006-05-11 Paul Brook + + * config/tc-arm.c (parse_half): New function. + (operand_parse_code): Remove OP_Iffff. Add OP_HALF. + (parse_operands): Ditto. + (do_mov16): Reject invalid relocations. + (do_t_mov16): Ditto. Use Thumb reloc numbers. + (insns): Replace Iffff with HALF. + (md_apply_fix): Add MOVW and MOVT relocs. + (tc_gen_reloc): Ditto. + * doc/c-arm.texi: Document relocation operators + 2006-05-11 Paul Brook * config/tc-arm.c (arm_fix_adjustable): Return 0 for function symbols. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 50940dc47e0..8d19407db68 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -4435,6 +4435,46 @@ parse_address (char **str, int i) return SUCCESS; } +/* Parse an operand for a MOVW or MOVT instruction. */ +static int +parse_half (char **str) +{ + char * p; + + p = *str; + skip_past_char (&p, '#'); + if (strncasecmp (p, ":lower16:", 9) == 0) + inst.reloc.type = BFD_RELOC_ARM_MOVW; + else if (strncasecmp (p, ":upper16:", 9) == 0) + inst.reloc.type = BFD_RELOC_ARM_MOVT; + + if (inst.reloc.type != BFD_RELOC_UNUSED) + { + p += 9; + skip_whitespace(p); + } + + if (my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX)) + return FAIL; + + if (inst.reloc.type == BFD_RELOC_UNUSED) + { + if (inst.reloc.exp.X_op != O_constant) + { + inst.error = _("constant expression expected"); + return FAIL; + } + if (inst.reloc.exp.X_add_number < 0 + || inst.reloc.exp.X_add_number > 0xffff) + { + inst.error = _("immediate value out of range"); + return FAIL; + } + } + *str = p; + return SUCCESS; +} + /* Miscellaneous. */ /* Parse a PSR flag operand. The value returned is FAIL on syntax error, @@ -4925,7 +4965,6 @@ enum operand_parse_code OP_I64, /* 1 .. 64 */ OP_I64z, /* 0 .. 64 */ OP_I255, /* 0 .. 255 */ - OP_Iffff, /* 0 .. 65535 */ OP_I4b, /* immediate, prefix optional, 1 .. 4 */ OP_I7b, /* 0 .. 7 */ @@ -4937,6 +4976,7 @@ enum operand_parse_code OP_EXP, /* arbitrary expression */ OP_EXPi, /* same, with optional immediate prefix */ OP_EXPr, /* same, with optional relocation suffix */ + OP_HALF, /* 0 .. 65535 or low/high reloc. */ OP_CPSF, /* CPS flags */ OP_ENDI, /* Endianness specifier */ @@ -5197,7 +5237,6 @@ parse_operands (char *str, const unsigned char *pattern) case OP_I64: po_imm_or_fail ( 1, 64, FALSE); break; case OP_I64z: po_imm_or_fail ( 0, 64, FALSE); break; case OP_I255: po_imm_or_fail ( 0, 255, FALSE); break; - case OP_Iffff: po_imm_or_fail ( 0, 0xffff, FALSE); break; case OP_I4b: po_imm_or_fail ( 1, 4, TRUE); break; case OP_oI7b: @@ -5263,6 +5302,11 @@ parse_operands (char *str, const unsigned char *pattern) } break; + /* Operand for MOVW or MOVT. */ + case OP_HALF: + po_misc_or_fail (parse_half (&str)); + break; + /* Register or expression */ case OP_RR_EXr: po_reg_or_goto (REG_TYPE_RN, EXPr); break; case OP_RR_EXi: po_reg_or_goto (REG_TYPE_RN, EXPi); break; @@ -6438,10 +6482,22 @@ do_mov (void) static void do_mov16 (void) { + bfd_vma imm; + bfd_boolean top; + + top = (inst.instruction & 0x00400000) != 0; + constraint (top && inst.reloc.type == BFD_RELOC_ARM_MOVW, + _(":lower16: not allowed this instruction")); + constraint (!top && inst.reloc.type == BFD_RELOC_ARM_MOVT, + _(":upper16: not allowed instruction")); inst.instruction |= inst.operands[0].reg << 12; - /* The value is in two pieces: 0:11, 16:19. */ - inst.instruction |= (inst.operands[1].imm & 0x00000fff); - inst.instruction |= (inst.operands[1].imm & 0x0000f000) << 4; + if (inst.reloc.type == BFD_RELOC_UNUSED) + { + imm = inst.reloc.exp.X_add_number; + /* The value is in two pieces: 0:11, 16:19. */ + inst.instruction |= (imm & 0x00000fff); + inst.instruction |= (imm & 0x0000f000) << 4; + } } static void @@ -8709,11 +8765,30 @@ do_t_mov_cmp (void) static void do_t_mov16 (void) { + bfd_vma imm; + bfd_boolean top; + + top = (inst.instruction & 0x00800000) != 0; + if (inst.reloc.type == BFD_RELOC_ARM_MOVW) + { + constraint (top, _(":lower16: not allowed this instruction")); + inst.reloc.type = BFD_RELOC_ARM_THUMB_MOVW; + } + else if (inst.reloc.type == BFD_RELOC_ARM_MOVT) + { + constraint (!top, _(":upper16: not allowed this instruction")); + inst.reloc.type = BFD_RELOC_ARM_THUMB_MOVT; + } + inst.instruction |= inst.operands[0].reg << 8; - inst.instruction |= (inst.operands[1].imm & 0xf000) << 4; - inst.instruction |= (inst.operands[1].imm & 0x0800) << 15; - inst.instruction |= (inst.operands[1].imm & 0x0700) << 4; - inst.instruction |= (inst.operands[1].imm & 0x00ff); + if (inst.reloc.type == BFD_RELOC_UNUSED) + { + imm = inst.reloc.exp.X_add_number; + inst.instruction |= (imm & 0xf000) << 4; + inst.instruction |= (imm & 0x0800) << 15; + inst.instruction |= (imm & 0x0700) << 4; + inst.instruction |= (imm & 0x00ff); + } } static void @@ -13425,8 +13500,8 @@ static const struct asm_opcode insns[] = TCE(ubfx, 7e00050, f3c00000, 4, (RR, RR, I31, I32), bfx, t_bfx), TCE(mls, 0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla), - TCE(movw, 3000000, f2400000, 2, (RRnpc, Iffff), mov16, t_mov16), - TCE(movt, 3400000, f2c00000, 2, (RRnpc, Iffff), mov16, t_mov16), + TCE(movw, 3000000, f2400000, 2, (RRnpc, HALF), mov16, t_mov16), + TCE(movt, 3400000, f2c00000, 2, (RRnpc, HALF), mov16, t_mov16), TCE(rbit, 3ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit), TC3(ldrht, 03000b0, f8300e00, 2, (RR, ADDR), ldsttv4, t_ldstt), @@ -16761,6 +16836,47 @@ md_apply_fix (fixS * fixP, fixP->fx_done = 0; return; + case BFD_RELOC_ARM_MOVW: + case BFD_RELOC_ARM_MOVT: + case BFD_RELOC_ARM_THUMB_MOVW: + case BFD_RELOC_ARM_THUMB_MOVT: + if (fixP->fx_done || !seg->use_rela_p) + { + /* REL format relocations are limited to a 16-bit addend. */ + if (!fixP->fx_done) + { + if (value < -0x1000 || value > 0xffff) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("offset too big")); + } + else if (fixP->fx_r_type == BFD_RELOC_ARM_MOVT + || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT) + { + value >>= 16; + } + + if (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW + || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT) + { + newval = get_thumb32_insn (buf); + newval &= 0xfbf08f00; + newval |= (value & 0xf000) << 4; + newval |= (value & 0x0800) << 15; + newval |= (value & 0x0700) << 4; + newval |= (value & 0x00ff); + put_thumb32_insn (buf, newval); + } + else + { + newval = md_chars_to_number (buf, 4); + newval &= 0xfff0f000; + newval |= value & 0x0fff; + newval |= (value & 0xf000) << 4; + md_number_to_chars (buf, newval, 4); + } + } + return; + case BFD_RELOC_UNUSED: default: as_bad_where (fixP->fx_file, fixP->fx_line, @@ -16815,6 +16931,34 @@ tc_gen_reloc (asection *section, fixS *fixp) break; } + case BFD_RELOC_ARM_MOVW: + if (fixp->fx_pcrel) + { + code = BFD_RELOC_ARM_MOVW_PCREL; + break; + } + + case BFD_RELOC_ARM_MOVT: + if (fixp->fx_pcrel) + { + code = BFD_RELOC_ARM_MOVT_PCREL; + break; + } + + case BFD_RELOC_ARM_THUMB_MOVW: + if (fixp->fx_pcrel) + { + code = BFD_RELOC_ARM_THUMB_MOVW_PCREL; + break; + } + + case BFD_RELOC_ARM_THUMB_MOVT: + if (fixp->fx_pcrel) + { + code = BFD_RELOC_ARM_THUMB_MOVT_PCREL; + break; + } + case BFD_RELOC_NONE: case BFD_RELOC_ARM_PCREL_BRANCH: case BFD_RELOC_ARM_PCREL_BLX: diff --git a/gas/doc/c-arm.texi b/gas/doc/c-arm.texi index ca0998bea66..0b113f9894d 100644 --- a/gas/doc/c-arm.texi +++ b/gas/doc/c-arm.texi @@ -284,6 +284,7 @@ as position-independent code (PIC). @menu * ARM-Chars:: Special Characters * ARM-Regs:: Register Names +* ARM-Relocations:: Relocations @end menu @node ARM-Chars @@ -323,7 +324,46 @@ Either @samp{#} or @samp{$} can be used to indicate immediate operands. @cindex ARM floating point (@sc{ieee}) The ARM family uses @sc{ieee} floating-point numbers. +@node ARM-Relocations +@subsection ARM relocation generation +@cindex data relocations, ARM +@cindex ARM data relocations +Specific data relocations can be generated by putting the relocation name +in parentheses after the symbol name. For example: + +@smallexample + .word foo(TARGET1) +@end smallexample + +This will generate an @samp{R_ARM_TARGET1} relocation against the symbol +@var{foo}. +The following relocations are supported: +@code{GOT}, +@code{GOTOFF}, +@code{TARGET1}, +@code{TARGET2}, +@code{SBREL}, +@code{TLSGD}, +@code{TLSLDM}, +@code{TLSLDO}, +@code{GOTTPOFF} +and +@code{TPOFF}. + +For compatibility with older toolchains the assembler also accepts +@code{(PLT)} after branch targets. This will generate the deprecated +@samp{R_ARM_PLT32} relocation. + +@cindex MOVW and MOVT relocations, ARM +Relocations for @samp{MOVW} and @samp{MOVT} instructions can be generated +by prefixing the value with @samp{#:lower16:} and @samp{#:upper16} +respectively. For example to load the 32-bit addresss of foo into r0: + +@smallexample + MOVW r0, #:lower16:foo + MOVT r0, #:upper16:foo +@end smallexample @node ARM Directives @section ARM Machine Directives diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 828dce1ea0d..efe7187ba69 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2006-05-11 Paul Brook + + * ld-arm/arm-elf.exp: Add arm-movwt. + * ld-arm/arm-movwt.d: New test. + * ld-arm/arm-movwt.s: New test. + * ld-arm/arm.ld: Add .far. + 2006-05-11 Mike Bland * ld-elf/stab.d: New. diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp index 1a9fc00aeb8..04aa09cf49d 100644 --- a/ld/testsuite/ld-arm/arm-elf.exp +++ b/ld/testsuite/ld-arm/arm-elf.exp @@ -122,6 +122,9 @@ set armelftests { {"thumb-rel32" "-static -T arm.ld" "" {thumb-rel32.s} {{objdump -s thumb-rel32.d}} "thumb-rel32"} + {"MOVW/MOVT" "-static -T arm.ld" "" {arm-movwt.s} + {{objdump -dw arm-movwt.d}} + "arm-movwt"} } run_ld_link_tests $armelftests diff --git a/ld/testsuite/ld-arm/arm-movwt.d b/ld/testsuite/ld-arm/arm-movwt.d new file mode 100644 index 00000000000..bf551648d6d --- /dev/null +++ b/ld/testsuite/ld-arm/arm-movwt.d @@ -0,0 +1,39 @@ + +.*: file format.* + +Disassembly of section .text: + +00008000 <[^>]*>: + 8000: e3000000 movw r0, #0 ; 0x0 + 8004: e3411234 movt r1, #4660 ; 0x1234 + 8008: e3082000 movw r2, #32768 ; 0x8000 + 800c: e3413233 movt r3, #4659 ; 0x1233 + 8010: e3004011 movw r4, #17 ; 0x11 + 8014: e3415234 movt r5, #4660 ; 0x1234 + 8018: e3086011 movw r6, #32785 ; 0x8011 + 801c: e3417233 movt r7, #4659 ; 0x1233 + +00008020 <[^>]*>: + 8020: f240 0700 movw r7, #0 ; 0x0 + 8024: f2c1 2634 movt r6, #4660 ; 0x1234 + 8028: f248 0500 movw r5, #32768 ; 0x8000 + 802c: f2c1 2433 movt r4, #4659 ; 0x1233 + 8030: f240 0311 movw r3, #17 ; 0x11 + 8034: f2c1 2234 movt r2, #4660 ; 0x1234 + 8038: f248 0111 movw r1, #32785 ; 0x8011 + 803c: f2c1 2033 movt r0, #4659 ; 0x1233 + +Disassembly of section .far: + +12340000 <[^>]*>: +12340000: e3080000 movw r0, #32768 ; 0x8000 +12340004: e34e0dcc movt r0, #60876 ; 0xedcc +12340008: e3080021 movw r0, #32801 ; 0x8021 +1234000c: e34e0dcc movt r0, #60876 ; 0xedcc + +12340010 <[^>]*>: +12340010: f248 0000 movw r0, #32768 ; 0x8000 +12340014: f6ce 50cc movt r0, #60876 ; 0xedcc +12340018: f248 0021 movw r0, #32801 ; 0x8021 +1234001c: f6ce 50cc movt r0, #60876 ; 0xedcc + diff --git a/ld/testsuite/ld-arm/arm-movwt.s b/ld/testsuite/ld-arm/arm-movwt.s new file mode 100644 index 00000000000..ba8b1c5c2f3 --- /dev/null +++ b/ld/testsuite/ld-arm/arm-movwt.s @@ -0,0 +1,44 @@ + .text + .arch armv6t2 + .syntax unified + .global _start + .type _start, %function +_start: +base1: +arm1: + movw r0, #:lower16:arm2 + movt r1, #:upper16:arm2 + movw r2, #:lower16:(arm2 - arm1) + movt r3, #:upper16:(arm2 - arm1) + movw r4, #:lower16:thumb2 + movt r5, #:upper16:thumb2 + movw r6, #:lower16:(thumb2 - arm1) + movt r7, #:upper16:(thumb2 - arm1) + .thumb + .type thumb1, %function + .thumb_func +thumb1: + movw r7, #:lower16:arm2 + movt r6, #:upper16:arm2 + movw r5, #:lower16:(arm2 - arm1) + movt r4, #:upper16:(arm2 - arm1) + movw r3, #:lower16:thumb2 + movt r2, #:upper16:thumb2 + movw r1, #:lower16:(thumb2 - arm1) + movt r0, #:upper16:(thumb2 - arm1) + + .section .far, "ax", %progbits + .arm +arm2: + movw r0, #:lower16:(arm1 - arm2) + movt r0, #:upper16:(arm1 - arm2) + movw r0, #:lower16:(thumb1 - arm2) + movt r0, #:upper16:(thumb1 - arm2) + .thumb + .type thumb2, %function + .thumb_func +thumb2: + movw r0, #:lower16:(arm1 - arm2) + movt r0, #:upper16:(arm1 - arm2) + movw r0, #:lower16:(thumb1 - arm2) + movt r0, #:upper16:(thumb1 - arm2) diff --git a/ld/testsuite/ld-arm/arm.ld b/ld/testsuite/ld-arm/arm.ld index 4ef7d824ec2..c9e01e65a82 100644 --- a/ld/testsuite/ld-arm/arm.ld +++ b/ld/testsuite/ld-arm/arm.ld @@ -14,5 +14,7 @@ SECTIONS } =0 . = 0x9000; .got : { *(.got) *(.got.plt)} + . = 0x12340000; + .far : { *(.far) } .ARM.attribues 0 : { *(.ARM.atttributes) } } -- 2.30.2