4ad/go.arm64

liblink: 7a mis-assembles STLR

davecheney opened this issue · 8 comments

TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16
        MOV     addr+0(FP), R0
        MOV     val+8(FP), R1
        STLR    R1, (R0)
        RETURN

Becomes

(gdb) disassemble /r
Dump of assembler code for function runtime.atomicstore64:
   0x0000000000124740 <+0>:     e0 07 40 f9     ldr     x0, [sp,#8]
   0x0000000000124744 <+4>:     e1 0b 40 f9     ldr     x1, [sp,#16]
=> 0x0000000000124748 <+8>:     01 fc a0 c8     .inst   0xc8a0fc01 ; undefined
   0x000000000012474c <+12>:    c0 03 5f d6     ret
End of assembler dump.

And results in a delightful SIGILL

Looks like STLRW is also broken, but LDAR and LDARW are fine

(gdb) disassemble 'runtime.atomicstore'
Dump of assembler code for function runtime.atomicstore:
   0x0000000000124730 <+0>:     ldr     x0, [sp,#8]
   0x0000000000124734 <+4>:     ldrsw   x1, [sp,#16]
   0x0000000000124738 <+8>:     .inst   0x88a0fc01 ; undefined
   0x000000000012473c <+12>:    ret
End of assembler dump.
(gdb) disassemble 'runtime.atomicload' 
Dump of assembler code for function runtime.atomicload:
   0x00000000001246f0 <+0>:     ldr     x0, [sp,#8]
   0x00000000001246f4 <+4>:     ldar    w0, [x0]
   0x00000000001246f8 <+8>:     str     w0, [sp,#16]
   0x00000000001246fc <+12>:    ret
End of assembler dump.
(gdb) disassemble 'runtime.atomicload64'
Dump of assembler code for function runtime.atomicload64:
   0x0000000000124700 <+0>:     ldr     x0, [sp,#8]
   0x0000000000124704 <+4>:     ldar    x0, [x0]
   0x0000000000124708 <+8>:     str     x0, [sp,#16]
   0x000000000012470c <+12>:    ret

This seems to help

diff --git a/src/liblink/asm7.c b/src/liblink/asm7.c
index 84cd96d..a0e8262 100644
--- a/src/liblink/asm7.c
+++ b/src/liblink/asm7.c
@@ -2645,7 +2645,7 @@ if(0 /*debug['P']*/) print("%ux: %P       type %d\n", (uint32)(p->pc), p, o->type);
                break;
        case 59: /* stxr/stlxr */
                o1 = opstore(ctxt, p->as);
-               o1 |= p->to3.reg << 16;
+               o1 |= 0x1F << 16;
                if(p->from3.type != D_NONE)
                        o1 |= p->from3.reg << 10;
                else

(from looking at the difference between the ldar/stlr handling)

stxr and stlr are not the same thing, I think the optab entry which
forwards ASTLR to case 59 is wrong.

On Mon, Feb 2, 2015 at 6:33 PM, Michael Hudson-Doyle <
notifications@github.com> wrote:

This seems to help

diff --git a/src/liblink/asm7.c b/src/liblink/asm7.c
index 84cd96d..a0e8262 100644--- a/src/liblink/asm7.c+++ b/src/liblink/asm7.c@@ -2645,7 +2645,7 @@ if(0 /debug['P']/) print("%ux: %P type %d\n", (uint32)(p->pc), p, o->type);
break;
case 59: /* stxr/stlxr */
o1 = opstore(ctxt, p->as);- o1 |= p->to3.reg << 16;+ o1 |= 0x1F << 16;
if(p->from3.type != D_NONE)
o1 |= p->from3.reg << 10;
else

(from looking at the difference between the ldar/stlr handling)


Reply to this email directly or view it on GitHub
https://github.com/4ad/go/issues/82#issuecomment-72416205.

4ad commented

STLR and STXR should be handled by the same case in asmout just the way ldar/ldxr/ldaxr are. I think mwhudson is correct. I'll fix it.

STLR and STXR are different, the former is a two register form, the latter
is a three register form.

On Mon, Feb 2, 2015 at 9:53 PM, Aram Hăvărneanu notifications@github.com
wrote:

STLR and STXR should be handled by the same case in asmout just the way
ldar/ldxr/ldaxr are. I think mwhudson is correct. I'll fix it.


Reply to this email directly or view it on GitHub
https://github.com/4ad/go/issues/82#issuecomment-72438248.

4ad commented

Doesn't matter for liblink. Liblink doesn't really care about the number of arguments for an instruction, only where the opcode bits are. STLR is exactly like STXR, but the slot for the register is filled with ones.

4ad commented

STXP is really broken though.

4ad commented

Fixed in c885379.