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.
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.
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.
STXP is really broken though.