From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <77525476571d85282989a8a1ebe187a6@felloff.net> Date: Wed, 1 Apr 2015 03:34:25 +0200 From: cinap_lenrek@felloff.net To: 9fans@9fans.net MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Subject: [9fans] mips linker hoisting stack freeing operation Topicbox-Message-UUID: 4c690d38-ead9-11e9-9d60-3106f5b1d025 Point Pt(int x, int y) { int buf[1000]; /* added for demonstration */ Point p; buf[0] = x; p.x = x; p.y = y; return p; } vc -S compiler output looks ok, but i dont quite understand why it doesnt directly move x and y to the caller passed storage in R1: TEXT Pt+0(SB),0,$4012 MOVW y+8(FP),R8 MOVW x+4(FP),R7 MOVW R1,.ret+0(FP) MOVW R7,buf-4000(SP) MOVW R7,p-4008(SP) MOVW R8,p-4004(SP) MOVW .ret+0(FP),R4 MOVW $p-4008(SP),R6 MOVW 0(R6),R2 MOVW 4(R6),R3 MOVW R2,0(R4) MOVW R3,4(R4) RET , and after linking it becomes: Pt 0x00004020 ADD $-0xfb0,R29 /* allocate stack frame */ Pt+0x4 0x00004024 MOVW R1,.ret+4(FP) Pt+0x8 0x00004028 ADDU $0x8,R29,R6 /* local p */ Pt+0xc 0x0000402c MOVW .ret+4(FP),R4 Pt+0x10 0x00004030 MOVW x+8(FP),R7 Pt+0x14 0x00004034 MOVW y+12(FP),R8 Pt+0x18 0x00004038 MOVW R7,buf+16(SP) Pt+0x1c 0x0000403c MOVW R7,p+8(SP) Pt+0x20 0x00004040 MOVW R8,0xc(R29) Pt+0x24 0x00004044 ADD $0xfb0,R29 /* free stack frame (now R6 < SP) */ Pt+0x28 0x00004048 MOVW 0x0(R6),R2 /* p.x = x; NEIN! */ Pt+0x2c 0x0000404c MOVW 0x4(R6),R3 /* p.y = y; NEIN! */ Pt+0x30 0x00004050 MOVW R2,0x0(R4) /* ret->x = p.x */ Pt+0x34 0x00004054 JMP (R31) Pt+0x38 0x00004058 MOVW R3,0x4(R4) /* ret->y = p.y */ the problem appears to be the linker hoisting the ADD $const,SP up. this works until we hit a interrupt or a note, then the local variables get corrupted. and this is not the interrupt handlers fault, as this depends on the size of the local variables of the function, not some fixed redzone area. (thats what int buf[1000] is trying to demonstrate). theres my attempt at preventing the linker from doing so: diff -r 192be1470c05 -r 359ae373800c sys/src/cmd/vl/sched.c --- a/sys/src/cmd/vl/sched.c Mon Mar 30 20:53:49 2015 -0400 +++ b/sys/src/cmd/vl/sched.c Wed Apr 01 01:30:16 2015 +0200 @@ -85,7 +85,7 @@ for(t=s+1; t<=se; t++) { if(!(t->p.mark & LOAD)) continue; - if(t->p.mark & BRANCH) + if(t->p.mark & BRANCH || t->set.ireg & (1<p.mark & BRANCH) + if(t->p.mark & BRANCH || t->set.ireg & (1< sch && conflict(s-1, t)) continue; which seems to work in this case: Pt 0x00004020 ADD $-0xfb0,R29 /* allocate stackframe */ Pt+0x4 0x00004024 MOVW R1,.ret+4(FP) Pt+0x8 0x00004028 ADDU $0x8,R29,R6 Pt+0xc 0x0000402c MOVW .ret+4(FP),R4 Pt+0x10 0x00004030 MOVW x+8(FP),R7 Pt+0x14 0x00004034 MOVW y+12(FP),R8 Pt+0x18 0x00004038 MOVW R7,buf+16(SP) Pt+0x1c 0x0000403c MOVW R7,p+8(SP) Pt+0x20 0x00004040 MOVW R8,0xc(R29) Pt+0x24 0x00004044 MOVW 0x0(R6),R2 /* p.x = x; JA! */ Pt+0x28 0x00004048 MOVW 0x4(R6),R3 /* p.y = y; JA! */ Pt+0x2c 0x0000404c MOVW R2,0x0(R4) /* ret->x = p.x */ Pt+0x30 0x00004050 MOVW R3,0x4(R4) /* ret->y = p.y */ Pt+0x34 0x00004054 JMP (R31) Pt+0x38 0x00004058 ADD $0xfb0,R29 /* free stack frame last */ any comments (charles)? -- cinap