This is an archive of the discontinued LLVM Phabricator instance.

[Sparc] Support calls to absolute addresses
Needs ReviewPublic

Authored by dcederman on May 18 2017, 1:11 AM.

Details

Reviewers
jyknight
venkatra
Summary

I will split it out the printout related code if the patch gets accepted.

Diff Detail

Event Timeline

dcederman created this revision.May 18 2017, 1:11 AM
jyknight edited edge metadata.May 22 2017, 3:46 PM

The current behavior is definitely wrong...but I think this isn't a correct fix either.

Per the behavior of both GNU as and Solaris as, "call NUM" should actually be an alias for "jmpl NUM, %o7", so I think isImm shouldn't be supported in getCallTargetOpValue at all -- and the tabledefs should be modified so that it's impossible to get into that code with an immediate.

(While I look at this, though, I notice that the *disassembly* is bogus in both gnu "objdump" and solaris "dis". They both output a relative call using the text "call NUM" -- they print a relative call using syntax which is parsed on input as an absolute call. Ugh. llvm-objdump at least prints the two differently and basically consistent with the assembler, but its assembler is wrong.)

Given a test file test.s:

call 1
call 4
call 0x1232
call . + 1
call . + 4
call . + 0x1232

With GNU as: "as -o test.o test.s". Note the difference in instruction encodings for the first 3 vs last 3. (I note also that "call . + 1" should really be an error, since it's unencodable, but that's a different issue.)

"objdump -d test.o":

00000000 <.text>:
   0:   9f c0 20 01     call  1
   4:   9f c0 20 04     call  4
   8:   9f c0 24 d2     call  0x4d0
   c:   40 00 00 00     call  0xc
  10:   40 00 00 01     call  0x14
  14:   40 00 01 34     call  0x4e4

"llvm-objdump -d test.o":

.text:
       0:       9f c0 20 01     call %g0+1
       4:       9f c0 20 04     call %g0+4
       8:       9f c0 24 d2     call %g0+1232
       c:       40 00 00 00     call 0
      10:       40 00 00 01     call 4
      14:       40 00 01 34     call 1232

With "clang -fintegrated-as -c -target sparc-unknown-unknown -o test.o test.s", note that we incorrectly encoded everything as relative calls.

"objdump -d test.o":

00000000 <.text>:
   0:   40 00 00 01     call  0x4
   4:   40 00 00 04     call  0x14
   8:   40 00 04 d2     call  0x1350
   c:   40 00 00 00     call  0xc
  10:   40 00 00 01     call  0x14
  14:   40 00 01 34     call  0x4e4

Sorry for the very late reply, I missed that you had commented.

It seems GNU as generates a "jmpl %g0 + imm, %o7" when the target address value is small enough, and a call with a R_SPARC_WDISP30 and the target address as a constant when it is too big. To avoid having to modify parseMEMOperand() we could use the latter method in both cases. It generates the same number of instructions and it is not commonly used.

dcederman updated this revision to Diff 142905.Apr 18 2018, 4:02 AM
dcederman retitled this revision from [Sparc] Do not encode the 2 LSBs of the address in the call instruction to [Sparc] Support calls to absolute addresses.
dcederman edited the summary of this revision. (Show Details)