PR30715, VAX: md_create_long_jump
authorKalvis Duckmanton <kalvisd@gmail.com>
Sat, 12 Aug 2023 04:57:00 +0000 (14:27 +0930)
committerAlan Modra <amodra@gmail.com>
Sat, 12 Aug 2023 06:56:41 +0000 (16:26 +0930)
PR 30715
* config/tc-vax.c (md_create_long_jump): Use pc-relative addressing.
* testsuite/gas/vax/broken_word.d,
* testsuite/gas/vax/broken_word.s: New test.
* testsuite/gas/vax/vax.exp: Run it.

gas/config/tc-vax.c
gas/testsuite/gas/vax/broken_word.d [new file with mode: 0644]
gas/testsuite/gas/vax/broken_word.s [new file with mode: 0644]
gas/testsuite/gas/vax/vax.exp

index 50adf532a15e1f2561ad56a5c55bebf53e7ec4ec..d1a2998cdf5f24591a79e53e0cf02f009f2b097c 100644 (file)
@@ -2178,18 +2178,19 @@ md_create_short_jump (char *ptr,
 
 void
 md_create_long_jump (char *ptr,
-                    addressT from_addr ATTRIBUTE_UNUSED,
+                    addressT from_addr,
                     addressT to_addr,
-                    fragS *frag,
-                    symbolS *to_symbol)
+                    fragS *frag ATTRIBUTE_UNUSED,
+                    symbolS *to_symbol ATTRIBUTE_UNUSED)
 {
   valueT offset;
 
-  offset = to_addr - S_GET_VALUE (to_symbol);
-  *ptr++ = VAX_JMP;            /* Arbitrary jump.  */
-  *ptr++ = VAX_ABSOLUTE_MODE;
+  /* account for 1 byte instruction, 1 byte of address specifier and
+     4 bytes of offset from PC */
+  offset = to_addr - (from_addr + 1 + 1 + 4);
+  *ptr++ = VAX_JMP;         /* long jump */
+  *ptr++ = VAX_PC_RELATIVE_MODE;
   md_number_to_chars (ptr, offset, 4);
-  fix_new (frag, ptr - frag->fr_literal, 4, to_symbol, (long) 0, 0, NO_RELOC);
 }
 \f
 #ifdef OBJ_VMS
diff --git a/gas/testsuite/gas/vax/broken_word.d b/gas/testsuite/gas/vax/broken_word.d
new file mode 100644 (file)
index 0000000..8040b4f
--- /dev/null
@@ -0,0 +1,62 @@
+#as:
+#objdump: -dr
+
+.*:     file format .*
+
+
+Disassembly of section .text:
+
+00000000 <asmfn>:
+       0:      00 00           \.word 0x0000 # Entry mask: < >
+       2:      c2 04 5e        subl2 \$0x4,sp
+       5:      d0 ac 04 50     movl 0x4\(ap\),r0
+       9:      cf 50 01 02     casel r0,\$0x1,\$0x2
+
+0000000d <\.casetable>:
+       d:      1d 00 85 7f 09 00  .*
+
+00000013 <\.casetableend>:
+      13:      31 06 00        brw 1c <casedefault>
+      16:      17 ef 87 83     jmp 83a3 <case3>
+      1a:      00 00 *
+
+0000001c <casedefault>:
+      1c:      df ef 00 00     pushal .*
+      20:      00 00 *
+                       1e: R_VAX_PC32  \.rodata\+0x18
+      22:      fb 01 ef 00     calls \$0x1,.*
+      26:      00 00 00 *
+                       25: R_VAX_PC32  printf
+
+00000029 <asmret>:
+      29:      04              ret
+
+0000002a <case1>:
+      2a:      df ef 00 00     pushal .*
+      2e:      00 00 *
+                       2c: R_VAX_PC32  \.rodata
+      30:      fb 01 ef 00     calls \$0x1,.*
+      34:      00 00 00 *
+                       33: R_VAX_PC32  printf
+      37:      17 af ef        jmp 29 <asmret>
+       \.\.\.
+
+00007f92 <case2>:
+    7f92:      df ef 00 00     pushal .*
+    7f96:      00 00 *
+                       7f94: R_VAX_PC32        \.rodata\+0x8
+    7f98:      fb 01 ef 00     calls \$0x1,.*
+    7f9c:      00 00 00 *
+                       7f9b: R_VAX_PC32        printf
+    7f9f:      17 cf 86 80     jmp 29 <asmret>
+       \.\.\.
+
+000083a3 <case3>:
+    83a3:      df ef 00 00     pushal .*
+    83a7:      00 00 *
+                       83a5: R_VAX_PC32        \.rodata\+0x10
+    83a9:      fb 01 ef 00     calls \$0x1,.*
+    83ad:      00 00 00 *
+                       83ac: R_VAX_PC32        printf
+    83b0:      17 ef 73 7c     jmp 29 <asmret>
+    83b4:      ff ff *
diff --git a/gas/testsuite/gas/vax/broken_word.s b/gas/testsuite/gas/vax/broken_word.s
new file mode 100644 (file)
index 0000000..445b0bc
--- /dev/null
@@ -0,0 +1,57 @@
+       .text
+
+       .globl  printf
+
+       .globl asmfn
+       .type   asmfn, @function
+asmfn:
+       .word 0
+       subl2 $4,%sp
+       movl 4(%ap), %r0
+
+       casel   %r0, $1, $(3 - 1)
+       .type   .casetable, @object
+.casetable:
+       .word   case1 - .casetable
+       .word   case2 - .casetable
+       .word   case3 - .casetable
+# define a label here for disassembly of magically added branch and jump
+.casetableend = .casetable + 6
+       .type   .casetableend, @notype
+
+casedefault:
+       pushal  msg_default
+       calls   $1, printf
+asmret:
+       ret
+
+# Case1 is close by, within the range of a word offset
+case1:
+       pushal  msg_case1
+       calls   $1, printf
+       jmp     asmret
+       .skip   32600
+
+# Case2 is still within the range of a signed word offset
+case2:
+       pushal  msg_case2
+       calls   $1, printf
+       jmp     asmret
+       .skip   1024
+
+# Case3 is now no longer within the range of a signed word offset
+case3:
+       pushal  msg_case3
+       calls   $1, printf
+       jmp     asmret
+
+
+       .section        .rodata
+msg_case1:
+       .string "Case 1\n"
+msg_case2:
+       .string "Case 2\n"
+msg_case3:
+       .string "Case 3\n"
+msg_default:
+       .string "Default case\n"
index f7f6afe5a1c89e82fce7258e684a10a246fc1cc2..5acaf5e860e46663ce2561d20b9207f5f1c7a01b 100644 (file)
@@ -17,6 +17,9 @@
 #
 # Some generic VAX tests
 #
+if ![istarget vax-*-* ] then {
+    return
+}
 
 proc do_quad {} {
     set testname "quad.s: quadword immediate values"
@@ -42,12 +45,12 @@ proc do_quad {} {
     if [all_ones $x1 $x2 $x3] then { pass $testname } else { fail $testname }
 }
 
-if [istarget vax-*-* ] then {
-    do_quad
 
-    run_dump_test "flonum"
+do_quad
 
-    if { [istarget vax-*-*elf*] || [istarget vax-*-linux-*] } then {
-       run_dump_test "elf-rel"
-    }
+run_dump_test flonum
+run_dump_test broken_word
+
+if { [istarget vax-*-*elf*] || [istarget vax-*-linux-*] } then {
+    run_dump_test elf-rel
 }