diff options
-rw-r--r-- | gas/config/tc-loongarch.c | 70 | ||||
-rw-r--r-- | gas/testsuite/gas/loongarch/relax-align-ignore-start.d (renamed from gas/testsuite/gas/loongarch/relax-align-first.d) | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/loongarch/relax-align-ignore-start.s (renamed from gas/testsuite/gas/loongarch/relax-align-first.s) | 0 | ||||
-rw-r--r-- | include/opcode/loongarch.h | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/dwarf.exp | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-loongarch-elf/partial-link-align-a.s | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-loongarch-elf/partial-link-align-b.s | 3 | ||||
-rw-r--r-- | ld/testsuite/ld-loongarch-elf/relax-align-ignore-start.d (renamed from ld/testsuite/ld-loongarch-elf/relax-align-first.d) | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-loongarch-elf/relax-align-ignore-start.s (renamed from ld/testsuite/ld-loongarch-elf/relax-align-first.s) | 0 | ||||
-rw-r--r-- | ld/testsuite/ld-loongarch-elf/relax.exp | 32 | ||||
-rw-r--r-- | ld/testsuite/ld-undefined/undefined.exp | 2 |
11 files changed, 95 insertions, 23 deletions
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c index d156477..00b8c80 100644 --- a/gas/config/tc-loongarch.c +++ b/gas/config/tc-loongarch.c @@ -139,15 +139,17 @@ enum options OPTION_ABI, OPTION_FLOAT_ABI, - OPTION_FLOAT_ISA, OPTION_LA_LOCAL_WITH_ABS, OPTION_LA_GLOBAL_WITH_PCREL, OPTION_LA_GLOBAL_WITH_ABS, + OPTION_RELAX, OPTION_NO_RELAX, + OPTION_THIN_ADD_SUB, + OPTION_IGNORE_START_ALIGN, OPTION_END_OF_ENUM, }; @@ -165,6 +167,7 @@ struct option md_longopts[] = { "mrelax", no_argument, NULL, OPTION_RELAX }, { "mno-relax", no_argument, NULL, OPTION_NO_RELAX }, { "mthin-add-sub", no_argument, NULL, OPTION_THIN_ADD_SUB}, + { "mignore-start-align", no_argument, NULL, OPTION_IGNORE_START_ALIGN}, { NULL, no_argument, NULL, 0 } }; @@ -247,6 +250,10 @@ md_parse_option (int c, const char *arg) LARCH_opts.thin_add_sub = 1; break; + case OPTION_IGNORE_START_ALIGN: + LARCH_opts.ignore_start_align = 1; + break; + case OPTION_IGNORE: break; @@ -1772,7 +1779,9 @@ md_show_usage (FILE *stream) -mthin-add-sub Convert a pair of R_LARCH_ADD32/64 and R_LARCH_SUB32/64 to\n\ R_LARCH_32/64_PCREL as much as possible\n\ The option does not affect the generation of R_LARCH_32_PCREL\n\ - relocations in .eh_frame\n")); + relocations in .eh_frame\n\ + -mignore-start-align Ignore .align if it is at the start of a section. This option\n\ + can't be used when partial linking (ld -r).\n")); } static void @@ -1794,39 +1803,60 @@ bool loongarch_frag_align_code (int n, int max) { char *nops; + expressionS ex; symbolS *s = NULL; - bfd_vma insn_alignment = 4; - bfd_vma bytes = (bfd_vma) 1 << n; - bfd_vma worst_case_bytes = bytes - insn_alignment; + /* When not relaxing, loongarch_handle_align handles code alignment. */ + if (!LARCH_opts.relax) + return false; + + bfd_vma align_bytes = (bfd_vma) 1 << n; + bfd_vma worst_case_bytes = align_bytes - 4; + bfd_vma addend = worst_case_bytes; + bool align_max = max > 0 && (bfd_vma) max < worst_case_bytes; /* If we are moving to a smaller alignment than the instruction size, then no alignment is required. */ - if (bytes <= insn_alignment) + if (align_bytes <= 4) return true; - /* When not relaxing, loongarch_handle_align handles code alignment. */ - if (!LARCH_opts.relax) - return false; - /* If max <= 0, ignore max. If max >= worst_case_bytes, max has no effect. Similar to gas/write.c relax_segment function rs_align_code case: if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype). */ - if (max > 0 && (bfd_vma) max < worst_case_bytes) + if (align_max) { s = symbol_find (now_seg->name); - worst_case_bytes = ALIGN_MAX_ADDEND (n, max); + addend = ALIGN_MAX_ADDEND (n, max); + } + + if (LARCH_opts.ignore_start_align) + { + frag_grow (worst_case_bytes); + /* Use relaxable frag for .align. + If .align at the start of section, do nothing. Section alignment can + ensure correct alignment. + If .align is not at the start of a section, reserve NOP instructions + and R_LARCH_ALIGN relocation. */ + nops = frag_var (rs_machine_dependent, worst_case_bytes, worst_case_bytes, + rs_align_code, s, addend, NULL); } + else + { + nops = frag_more (worst_case_bytes); + if (align_max) + { + ex.X_add_symbol = s; + ex.X_op = O_symbol; + } + else + ex.X_op = O_constant; + + ex.X_add_number = addend; - frag_grow (worst_case_bytes); - /* Use relaxable frag for .align. - If .align at the start of section, do nothing. Section alignment can - ensure correct alignment. - If .align is not at the start of a section, reserve NOP instructions - and R_LARCH_ALIGN relocation. */ - nops = frag_var (rs_machine_dependent, worst_case_bytes, worst_case_bytes, - rs_align_code, s, worst_case_bytes, NULL); + fix_new_exp (frag_now, nops - frag_now->fr_literal, 0, + &ex, false, BFD_RELOC_LARCH_ALIGN); + } /* Default write NOP for aligned bytes. */ loongarch_make_nops (nops, worst_case_bytes); diff --git a/gas/testsuite/gas/loongarch/relax-align-first.d b/gas/testsuite/gas/loongarch/relax-align-ignore-start.d index ec0698b..0a67392 100644 --- a/gas/testsuite/gas/loongarch/relax-align-first.d +++ b/gas/testsuite/gas/loongarch/relax-align-ignore-start.d @@ -1,4 +1,4 @@ -#as: +#as: -mignore-start-align #objdump: -dr .*:[ ]+file format .* diff --git a/gas/testsuite/gas/loongarch/relax-align-first.s b/gas/testsuite/gas/loongarch/relax-align-ignore-start.s index a4c3d68..a4c3d68 100644 --- a/gas/testsuite/gas/loongarch/relax-align-first.s +++ b/gas/testsuite/gas/loongarch/relax-align-ignore-start.s diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h index 251daf1..965a164 100644 --- a/include/opcode/loongarch.h +++ b/include/opcode/loongarch.h @@ -256,6 +256,7 @@ dec2 : [1-9][0-9]? int relax; int thin_add_sub; + int ignore_start_align; } LARCH_opts; extern size_t loongarch_insn_length (insn_t insn); diff --git a/ld/testsuite/ld-elf/dwarf.exp b/ld/testsuite/ld-elf/dwarf.exp index 6a63269..a4748a4 100644 --- a/ld/testsuite/ld-elf/dwarf.exp +++ b/ld/testsuite/ld-elf/dwarf.exp @@ -52,6 +52,9 @@ set build_tests { {"DWARF parse during linker error" "" "-fno-toplevel-reorder" {dwarf2a.c dwarf2b.c} {{error_output "dwarf2.err"}} "dwarf2.x"} +} + +set build_tests_dwarf3 { {"Handle no DWARF information" "" "-g0" {dwarf3.c} {{error_output "dwarf3.err"}} "dwarf3.x"} @@ -72,6 +75,8 @@ set run_tests { set old_CFLAGS "$CFLAGS_FOR_TARGET" append CFLAGS_FOR_TARGET " $NOSANITIZE_CFLAGS" run_cc_link_tests $build_tests +setup_xfail loongarch*-*-* +run_cc_link_tests $build_tests_dwarf3 run_ld_link_exec_tests $run_tests set CFLAGS_FOR_TARGET "$old_CFLAGS" diff --git a/ld/testsuite/ld-loongarch-elf/partial-link-align-a.s b/ld/testsuite/ld-loongarch-elf/partial-link-align-a.s new file mode 100644 index 0000000..a8b4f29 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/partial-link-align-a.s @@ -0,0 +1,2 @@ +.text +la.local $t0, .text diff --git a/ld/testsuite/ld-loongarch-elf/partial-link-align-b.s b/ld/testsuite/ld-loongarch-elf/partial-link-align-b.s new file mode 100644 index 0000000..46fa058 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/partial-link-align-b.s @@ -0,0 +1,3 @@ +.text +.align 4 +ret diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-first.d b/ld/testsuite/ld-loongarch-elf/relax-align-ignore-start.d index 9a4fad8..939cf42 100644 --- a/ld/testsuite/ld-loongarch-elf/relax-align-first.d +++ b/ld/testsuite/ld-loongarch-elf/relax-align-ignore-start.d @@ -1,3 +1,4 @@ +#as: -mignore-start-align #ld: -e0 #objdump: -d diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-first.s b/ld/testsuite/ld-loongarch-elf/relax-align-ignore-start.s index 0a9115b..0a9115b 100644 --- a/ld/testsuite/ld-loongarch-elf/relax-align-first.s +++ b/ld/testsuite/ld-loongarch-elf/relax-align-ignore-start.s diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp index 2345214..890f139 100644 --- a/ld/testsuite/ld-loongarch-elf/relax.exp +++ b/ld/testsuite/ld-loongarch-elf/relax.exp @@ -19,10 +19,38 @@ # MA 02110-1301, USA. # -if [istarget loongarch64-*-*] { - run_dump_test "relax-align-first" +proc run_partial_linking_align_test {} { + global as + global ld + global srcdir + global subdir + global runtests + + set testname "partial-link-align" + if ![runtest_file_p $runtests $testname] then { + return + } + if { ![ld_assemble $as "$srcdir/$subdir/$testname-a.s" tmpdir/a.o] + || ![ld_assemble $as "$srcdir/$subdir/$testname-b.s" tmpdir/b.o] + || ![ld_link $ld tmpdir/$testname.os "tmpdir/a.o tmpdir/b.o -r"] + || ![ld_link $ld tmpdir/$testname "tmpdir/$testname.os -e0 -Ttext 0x1000"] } { + fail $testname + } else { + set objdump_output [run_host_cmd "objdump" "-d tmpdir/$testname"] + if { [ regexp ".*1010:\\s*4c000020\\s*jirl.*" $objdump_output ] } { + pass $testname + } else { + fail $testname + } + } +} + +if [istarget loongarch64-*-*] { if [isbuild loongarch64-*-*] { + run_dump_test "relax-align-ignore-start" + run_partial_linking_align_test + set testname "loongarch relax .exe build" set pre_builds [list \ [list \ diff --git a/ld/testsuite/ld-undefined/undefined.exp b/ld/testsuite/ld-undefined/undefined.exp index 6f7ea00..2cc67fe 100644 --- a/ld/testsuite/ld-undefined/undefined.exp +++ b/ld/testsuite/ld-undefined/undefined.exp @@ -74,6 +74,7 @@ if { ![check_compiler_available] } { # in a literal pool outside the function, so that both the # "undefined function" and "undefined line" tests fail. setup_xfail xtensa*-*-linux* + setup_xfail loongarch*-*-* set mf "tmpdir/undefined.o* in function `function':" checkund $mf $testfn @@ -154,6 +155,7 @@ if { ![check_compiler_available] } { # eBPF doesn't support dwarf yet. setup_xfail bpf-*-* + setup_xfail loongarch*-*-* checkund $ml $testline } |