1
0
mirror of https://github.com/golang/go synced 2024-11-22 21:30:02 -07:00

Adding a batch of missing system calls.

R=rsc
APPROVED=rsc
DELTA=1329  (1264 added, 1 deleted, 64 changed)
OCL=30040
CL=30158
This commit is contained in:
Kai Backman 2009-06-10 11:53:07 -07:00
parent f2201185ab
commit 528919520d
8 changed files with 1371 additions and 54 deletions

View File

@ -31,6 +31,11 @@ OFILES_386=\
vlop.$O\
vlrt.$O\
# arm-specific object files
OFILES_arm=\
vlop.$O\
vlrt.$O\
OFILES=\
array.$O\
asm.$O\

View File

@ -3,9 +3,9 @@
// license that can be found in the LICENSE file.
TEXT _rt0_arm(SB),7,$0
// copy arguments forward on an even stack
// MOVW $0(SP), R0
// MOVL 0(SP), R1 // argc
// copy arguments forward on an even stack
// MOVW $0(SP), R0
// MOVL 0(SP), R1 // argc
// LEAL 4(SP), R1 // argv
// SUBL $128, SP // plenty of scratch
// ANDL $~7, SP
@ -13,71 +13,193 @@ TEXT _rt0_arm(SB),7,$0
// MOVL BX, 124(SP)
// // write "go386\n"
// PUSHL $6
// PUSHL $hello(SB)
// PUSHL $1
// CALL sys·write(SB)
// POPL AX
// POPL AX
// POPL AX
// // write "go386\n"
// PUSHL $6
// PUSHL $hello(SB)
// PUSHL $1
// CALL sys·write(SB)
// POPL AX
// POPL AX
// POPL AX
// CALL ldt0setup(SB)
// CALL ldt0setup(SB)
// set up %fs to refer to that ldt entry
// MOVL $(7*8+7), AX
// MOVW AX, FS
// MOVL $(7*8+7), AX
// MOVW AX, FS
// // store through it, to make sure it works
// MOVL $0x123, 0(FS)
// MOVL tls0(SB), AX
// CMPL AX, $0x123
// JEQ ok
// MOVL AX, 0
// // store through it, to make sure it works
// MOVL $0x123, 0(FS)
// MOVL tls0(SB), AX
// CMPL AX, $0x123
// JEQ ok
// MOVL AX, 0
// ok:
// // set up m and g "registers"
// // g is 0(FS), m is 4(FS)
// LEAL g0(SB), CX
// MOVL CX, 0(FS)
// LEAL m0(SB), AX
// MOVL AX, 4(FS)
// // set up m and g "registers"
// // g is 0(FS), m is 4(FS)
// LEAL g0(SB), CX
// MOVL CX, 0(FS)
// LEAL m0(SB), AX
// MOVL AX, 4(FS)
// // save m->g0 = g0
// MOVL CX, 0(AX)
// // save m->g0 = g0
// MOVL CX, 0(AX)
// // create istack out of the OS stack
// LEAL (-8192+104)(SP), AX // TODO: 104?
// MOVL AX, 0(CX) // 8(g) is stack limit (w 104b guard)
// MOVL SP, 4(CX) // 12(g) is base
// CALL emptyfunc(SB) // fault if stack check is wrong
// // create istack out of the OS stack
// LEAL (-8192+104)(SP), AX // TODO: 104?
// MOVL AX, 0(CX) // 8(g) is stack limit (w 104b guard)
// MOVL SP, 4(CX) // 12(g) is base
// CALL emptyfunc(SB) // fault if stack check is wrong
// // convention is D is always cleared
// CLD
// // convention is D is always cleared
// CLD
// CALL check(SB)
// CALL check(SB)
// // saved argc, argv
// MOVL 120(SP), AX
// MOVL AX, 0(SP)
// MOVL 124(SP), AX
// MOVL AX, 4(SP)
// CALL args(SB)
// CALL osinit(SB)
// CALL schedinit(SB)
// // saved argc, argv
// MOVL 120(SP), AX
// MOVL AX, 0(SP)
// MOVL 124(SP), AX
// MOVL AX, 4(SP)
// CALL args(SB)
// CALL osinit(SB)
// CALL schedinit(SB)
// // create a new goroutine to start program
// PUSHL $mainstart(SB) // entry
// PUSHL $8 // arg size
// CALL sys·newproc(SB)
// POPL AX
// POPL AX
// // create a new goroutine to start program
// PUSHL $mainstart(SB) // entry
// PUSHL $8 // arg size
// CALL sys·newproc(SB)
// POPL AX
// POPL AX
// // start this M
// CALL mstart(SB)
// // start this M
// CALL mstart(SB)
BL main<EFBFBD>main(SB)
BL main·main(SB)
MOVW $99, R0
SWI $0x00900001
// TODO(kaib): remove these once linker works properly
// pull in dummy dependencies
// TEXT _dep_dummy(SB),7,$0
// BL sys·morestack(SB)
TEXT breakpoint(SB),7,$0
BL abort(SB)
// BYTE $0xcc
// RET
// go-routine
TEXT gogo(SB), 7, $0
BL abort(SB)
// MOVL 4(SP), AX // gobuf
// MOVL 0(AX), SP // restore SP
// MOVL 4(AX), AX
// MOVL AX, 0(SP) // put PC on the stack
// MOVL $1, AX
// RET
TEXT gosave(SB), 7, $0
BL abort(SB)
// MOVL 4(SP), AX // gobuf
// MOVL SP, 0(AX) // save SP
// MOVL 0(SP), BX
// MOVL BX, 4(AX) // save PC
// MOVL $0, AX // return 0
// RET
// support for morestack
// return point when leaving new stack.
// save AX, jmp to lesstack to switch back
TEXT retfromnewstack(SB),7,$0
BL abort(SB)
// MOVL 4(FS), BX // m
// MOVL AX, 12(BX) // save AX in m->cret
// JMP lessstack(SB)
// gogo, returning 2nd arg instead of 1
TEXT gogoret(SB), 7, $0
BL abort(SB)
// MOVL 8(SP), AX // return 2nd arg
// MOVL 4(SP), BX // gobuf
// MOVL 0(BX), SP // restore SP
// MOVL 4(BX), BX
// MOVL BX, 0(SP) // put PC on the stack
// RET
TEXT setspgoto(SB), 7, $0
BL abort(SB)
// MOVL 4(SP), AX // SP
// MOVL 8(SP), BX // fn to call
// MOVL 12(SP), CX // fn to return
// MOVL AX, SP
// PUSHL CX
// JMP BX
// POPL AX // not reached
// RET
// bool cas(int32 *val, int32 old, int32 new)
// Atomically:
// if(*val == old){
// *val = new;
// return 1;
// }else
// return 0;
TEXT cas(SB), 7, $0
BL abort(SB)
// MOVL 4(SP), BX
// MOVL 8(SP), AX
// MOVL 12(SP), CX
// LOCK
// CMPXCHGL CX, 0(BX)
// JZ 3(PC)
// MOVL $0, AX
// RET
// MOVL $1, AX
// RET
// void jmpdefer(fn, sp);
// called from deferreturn.
// 1. pop the caller
// 2. sub 5 bytes from the callers return
// 3. jmp to the argument
TEXT jmpdefer(SB), 7, $0
BL abort(SB)
// MOVL 4(SP), AX // fn
// MOVL 8(SP), BX // caller sp
// LEAL -4(BX), SP // caller sp after CALL
// SUBL $5, (SP) // return to CALL again
// JMP AX // but first run the deferred function
TEXT sys·memclr(SB),7,$0
BL abort(SB)
// MOVL 4(SP), DI // arg 1 addr
// MOVL 8(SP), CX // arg 2 count
// ADDL $3, CX
// SHRL $2, CX
// MOVL $0, AX
// CLD
// REP
// STOSL
// RET
TEXT sys·getcallerpc+0(SB),7,$0
BL abort(SB)
// MOVL x+0(FP),AX // addr of first arg
// MOVL -4(AX),AX // get calling pc
// RET
TEXT sys·setcallerpc+0(SB),7,$0
BL abort(SB)
// MOVL x+0(FP),AX // addr of first arg
// MOVL x+4(FP), BX
// MOVL BX, -4(AX) // set calling pc
// RET
TEXT abort(SB),7,$0
WORD $0

View File

@ -0,0 +1,147 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "runtime.h"
// TODO(rsc): Move this into portable code, with calls to a
// machine-dependent isclosure() function.
void
traceback(byte *pc0, byte *sp, G *g)
{
// Stktop *stk;
// uintptr pc;
// int32 i, n;
// Func *f;
// byte *p;
// pc = (uintptr)pc0;
// // If the PC is zero, it's likely a nil function call.
// // Start in the caller's frame.
// if(pc == 0) {
// pc = *(uintptr*)sp;
// sp += sizeof(uintptr);
// }
// stk = (Stktop*)g->stackbase;
// for(n=0; n<100; n++) {
// while(pc == (uintptr)retfromnewstack) {
// // pop to earlier stack block
// sp = stk->oldsp;
// stk = (Stktop*)stk->oldbase;
// pc = *(uintptr*)(sp+sizeof(uintptr));
// sp += 2*sizeof(uintptr); // two irrelevant calls on stack: morestack plus its call
// }
// f = findfunc(pc);
// if(f == nil) {
// // dangerous, but poke around to see if it is a closure
// p = (byte*)pc;
// // ADDL $xxx, SP; RET
// if(p[0] == 0x81 && p[1] == 0xc4 && p[6] == 0xc3) {
// sp += *(uint32*)(p+2) + 8;
// pc = *(uintptr*)(sp - 8);
// if(pc <= 0x1000)
// return;
// continue;
// }
// printf("%p unknown pc\n", pc);
// return;
// }
// if(f->frame < sizeof(uintptr)) // assembly funcs say 0 but lie
// sp += sizeof(uintptr);
// else
// sp += f->frame;
// // print this frame
// // main+0xf /home/rsc/go/src/runtime/x.go:23
// // main(0x1, 0x2, 0x3)
// printf("%S", f->name);
// if(pc > f->entry)
// printf("+%p", (uintptr)(pc - f->entry));
// printf(" %S:%d\n", f->src, funcline(f, pc-1)); // -1 to get to CALL instr.
// printf("\t%S(", f->name);
// for(i = 0; i < f->args; i++) {
// if(i != 0)
// prints(", ");
// sys·printhex(((uint32*)sp)[i]);
// if(i >= 4) {
// prints(", ...");
// break;
// }
// }
// prints(")\n");
// pc = *(uintptr*)(sp-sizeof(uintptr));
// if(pc <= 0x1000)
// return;
// }
// prints("...\n");
}
// func caller(n int) (pc uintptr, file string, line int, ok bool)
void
runtime·Caller(int32 n, uintptr retpc, String retfile, int32 retline, bool retbool)
{
// uintptr pc;
// byte *sp;
// byte *p;
// Stktop *stk;
// Func *f;
// // our caller's pc, sp.
// sp = (byte*)&n;
// pc = *((uintptr*)sp - 1);
// if((f = findfunc(pc)) == nil) {
// error:
// retpc = 0;
// retline = 0;
// retfile = emptystring;
// retbool = false;
// FLUSH(&retpc);
// FLUSH(&retfile);
// FLUSH(&retline);
// FLUSH(&retbool);
// return;
// }
// // now unwind n levels
// stk = (Stktop*)g->stackbase;
// while(n-- > 0) {
// while(pc == (uintptr)retfromnewstack) {
// sp = stk->oldsp;
// stk = (Stktop*)stk->oldbase;
// pc = *((uintptr*)sp + 1);
// sp += 2*sizeof(uintptr);
// }
// if(f->frame < sizeof(uintptr)) // assembly functions lie
// sp += sizeof(uintptr);
// else
// sp += f->frame;
// loop:
// pc = *((uintptr*)sp - 1);
// if(pc <= 0x1000 || (f = findfunc(pc)) == nil) {
// // dangerous, but let's try this.
// // see if it is a closure.
// p = (byte*)pc;
// // ADDL $xxx, SP; RET
// if(p[0] == 0x81 && p[1] == 0xc4 && p[6] == 0xc3) {
// sp += *(uint32*)(p+2) + sizeof(uintptr);
// goto loop;
// }
// goto error;
// }
// }
// retpc = pc;
// retfile = f->src;
// retline = funcline(f, pc-1);
// retbool = true;
// FLUSH(&retpc);
// FLUSH(&retfile);
// FLUSH(&retline);
// FLUSH(&retbool);
}

178
src/pkg/runtime/arm/vlop.s Normal file
View File

@ -0,0 +1,178 @@
// Inferno's libkern/vlop-arm.s
// http://code.google.com/p/inferno-os/source/browse/libkern/vlop-arm.s
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
// Portions Copyright 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#define UMULL(Rs,Rm,Rhi,Rlo,S) WORD $((14<<28)|(4<<21)|(S<<20)|(Rhi<<16)|(Rlo<<12)|(Rs<<8)|(9<<4)|Rm)
#define UMLAL(Rs,Rm,Rhi,Rlo,S) WORD $((14<<28)|(5<<21)|(S<<20)|(Rhi<<16)|(Rlo<<12)|(Rs<<8)|(9<<4)|Rm)
#define MUL(Rs,Rm,Rd,S) WORD $((14<<28)|(0<<21)|(S<<20)|(Rd<<16)|(Rs<<8)|(9<<4)|Rm)
arg=0
/* replaced use of R10 by R11 because the former can be the data segment base register */
TEXT _mulv(SB), $0
MOVW 8(FP), R9 /* l0 */
MOVW 4(FP), R11 /* h0 */
MOVW 16(FP), R4 /* l1 */
MOVW 12(FP), R5 /* h1 */
UMULL(4, 9, 7, 6, 0)
MUL(11, 4, 8, 0)
ADD R8, R7
MUL(9, 5, 8, 0)
ADD R8, R7
MOVW R6, 4(R(arg))
MOVW R7, 0(R(arg))
RET
/* multiply, add, and right-shift, yielding a 32-bit result, while
using 64-bit accuracy for the multiply -- for fast fixed-point math */
TEXT _mularsv(SB), $0
MOVW 4(FP), R11 /* m1 */
MOVW 8(FP), R8 /* a */
MOVW 12(FP), R4 /* rs */
MOVW $0, R9
UMLAL(0, 11, 9, 8, 0)
MOVW R8>>R4, R8
RSB $32, R4, R4
ORR R9<<R4, R8, R0
RET
Q = 0
N = 1
D = 2
CC = 3
TMP = 11
TEXT save<>(SB), 7, $0
MOVW R(Q), 0(FP)
MOVW R(N), 4(FP)
MOVW R(D), 8(FP)
MOVW R(CC), 12(FP)
MOVW R(TMP), R(Q) /* numerator */
MOVW 20(FP), R(D) /* denominator */
CMP $0, R(D)
BNE s1
SWI 0
/* MOVW -1(R(D)), R(TMP) /* divide by zero fault */
s1: RET
TEXT rest<>(SB), 7, $0
MOVW 0(FP), R(Q)
MOVW 4(FP), R(N)
MOVW 8(FP), R(D)
MOVW 12(FP), R(CC)
/*
* return to caller
* of rest<>
*/
MOVW 0(R13), R14
ADD $20, R13
B (R14)
TEXT div<>(SB), 7, $0
MOVW $32, R(CC)
/*
* skip zeros 8-at-a-time
*/
e1:
AND.S $(0xff<<24),R(Q), R(N)
BNE e2
SLL $8, R(Q)
SUB.S $8, R(CC)
BNE e1
RET
e2:
MOVW $0, R(N)
loop:
/*
* shift R(N||Q) left one
*/
SLL $1, R(N)
CMP $0, R(Q)
ORR.LT $1, R(N)
SLL $1, R(Q)
/*
* compare numerator to denominator
* if less, subtract and set quotent bit
*/
CMP R(D), R(N)
ORR.HS $1, R(Q)
SUB.HS R(D), R(N)
SUB.S $1, R(CC)
BNE loop
RET
TEXT _div(SB), 7, $16
BL save<>(SB)
CMP $0, R(Q)
BGE d1
RSB $0, R(Q), R(Q)
CMP $0, R(D)
BGE d2
RSB $0, R(D), R(D)
d0:
BL div<>(SB) /* none/both neg */
MOVW R(Q), R(TMP)
B out
d1:
CMP $0, R(D)
BGE d0
RSB $0, R(D), R(D)
d2:
BL div<>(SB) /* one neg */
RSB $0, R(Q), R(TMP)
B out
TEXT _mod(SB), 7, $16
BL save<>(SB)
CMP $0, R(D)
RSB.LT $0, R(D), R(D)
CMP $0, R(Q)
BGE m1
RSB $0, R(Q), R(Q)
BL div<>(SB) /* neg numerator */
RSB $0, R(N), R(TMP)
B out
m1:
BL div<>(SB) /* pos numerator */
MOVW R(N), R(TMP)
B out
TEXT _divu(SB), 7, $16
BL save<>(SB)
BL div<>(SB)
MOVW R(Q), R(TMP)
B out
TEXT _modu(SB), 7, $16
BL save<>(SB)
BL div<>(SB)
MOVW R(N), R(TMP)
B out
out:
BL rest<>(SB)
B out

743
src/pkg/runtime/arm/vlrt.c Executable file
View File

@ -0,0 +1,743 @@
// Inferno's libkern/vlrt-arm.c
// http://code.google.com/p/inferno-os/source/browse/libkern/vlrt-arm.c
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
// Portions Copyright 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
typedef unsigned long ulong;
typedef unsigned int uint;
typedef unsigned short ushort;
typedef unsigned char uchar;
typedef signed char schar;
#define SIGN(n) (1UL<<(n-1))
typedef struct Vlong Vlong;
struct Vlong
{
union
{
struct
{
ulong hi;
ulong lo;
};
struct
{
ushort hims;
ushort hils;
ushort loms;
ushort lols;
};
};
};
void abort(void);
void
_addv(Vlong *r, Vlong a, Vlong b)
{
ulong lo, hi;
lo = a.lo + b.lo;
hi = a.hi + b.hi;
if(lo < a.lo)
hi++;
r->lo = lo;
r->hi = hi;
}
void
_subv(Vlong *r, Vlong a, Vlong b)
{
ulong lo, hi;
lo = a.lo - b.lo;
hi = a.hi - b.hi;
if(lo > a.lo)
hi--;
r->lo = lo;
r->hi = hi;
}
void
_d2v(Vlong *y, double d)
{
union { double d; struct Vlong; } x;
ulong xhi, xlo, ylo, yhi;
int sh;
x.d = d;
xhi = (x.hi & 0xfffff) | 0x100000;
xlo = x.lo;
sh = 1075 - ((x.hi >> 20) & 0x7ff);
ylo = 0;
yhi = 0;
if(sh >= 0) {
/* v = (hi||lo) >> sh */
if(sh < 32) {
if(sh == 0) {
ylo = xlo;
yhi = xhi;
} else {
ylo = (xlo >> sh) | (xhi << (32-sh));
yhi = xhi >> sh;
}
} else {
if(sh == 32) {
ylo = xhi;
} else
if(sh < 64) {
ylo = xhi >> (sh-32);
}
}
} else {
/* v = (hi||lo) << -sh */
sh = -sh;
if(sh <= 10) {
ylo = xlo << sh;
yhi = (xhi << sh) | (xlo >> (32-sh));
} else {
/* overflow */
yhi = d; /* causes something awful */
}
}
if(x.hi & SIGN(32)) {
if(ylo != 0) {
ylo = -ylo;
yhi = ~yhi;
} else
yhi = -yhi;
}
y->hi = yhi;
y->lo = ylo;
}
void
_f2v(Vlong *y, float f)
{
_d2v(y, f);
}
double
_v2d(Vlong x)
{
if(x.hi & SIGN(32)) {
if(x.lo) {
x.lo = -x.lo;
x.hi = ~x.hi;
} else
x.hi = -x.hi;
return -((long)x.hi*4294967296. + x.lo);
}
return (long)x.hi*4294967296. + x.lo;
}
float
_v2f(Vlong x)
{
return _v2d(x);
}
static void
dodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
{
ulong numlo, numhi, denhi, denlo, quohi, quolo, t;
int i;
numhi = num.hi;
numlo = num.lo;
denhi = den.hi;
denlo = den.lo;
/*
* get a divide by zero
*/
if(denlo==0 && denhi==0) {
numlo = numlo / denlo;
}
/*
* set up the divisor and find the number of iterations needed
*/
if(numhi >= SIGN(32)) {
quohi = SIGN(32);
quolo = 0;
} else {
quohi = numhi;
quolo = numlo;
}
i = 0;
while(denhi < quohi || (denhi == quohi && denlo < quolo)) {
denhi = (denhi<<1) | (denlo>>31);
denlo <<= 1;
i++;
}
quohi = 0;
quolo = 0;
for(; i >= 0; i--) {
quohi = (quohi<<1) | (quolo>>31);
quolo <<= 1;
if(numhi > denhi || (numhi == denhi && numlo >= denlo)) {
t = numlo;
numlo -= denlo;
if(numlo > t)
numhi--;
numhi -= denhi;
quolo |= 1;
}
denlo = (denlo>>1) | (denhi<<31);
denhi >>= 1;
}
if(q) {
q->lo = quolo;
q->hi = quohi;
}
if(r) {
r->lo = numlo;
r->hi = numhi;
}
}
void
_divvu(Vlong *q, Vlong n, Vlong d)
{
if(n.hi == 0 && d.hi == 0) {
q->hi = 0;
q->lo = n.lo / d.lo;
return;
}
dodiv(n, d, q, 0);
}
void
_modvu(Vlong *r, Vlong n, Vlong d)
{
if(n.hi == 0 && d.hi == 0) {
r->hi = 0;
r->lo = n.lo % d.lo;
return;
}
dodiv(n, d, 0, r);
}
static void
vneg(Vlong *v)
{
if(v->lo == 0) {
v->hi = -v->hi;
return;
}
v->lo = -v->lo;
v->hi = ~v->hi;
}
void
_divv(Vlong *q, Vlong n, Vlong d)
{
long nneg, dneg;
if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
q->lo = (long)n.lo / (long)d.lo;
q->hi = ((long)q->lo) >> 31;
return;
}
nneg = n.hi >> 31;
if(nneg)
vneg(&n);
dneg = d.hi >> 31;
if(dneg)
vneg(&d);
dodiv(n, d, q, 0);
if(nneg != dneg)
vneg(q);
}
void
_modv(Vlong *r, Vlong n, Vlong d)
{
long nneg, dneg;
if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
r->lo = (long)n.lo % (long)d.lo;
r->hi = ((long)r->lo) >> 31;
return;
}
nneg = n.hi >> 31;
if(nneg)
vneg(&n);
dneg = d.hi >> 31;
if(dneg)
vneg(&d);
dodiv(n, d, 0, r);
if(nneg)
vneg(r);
}
void
_rshav(Vlong *r, Vlong a, int b)
{
long t;
t = a.hi;
if(b >= 32) {
r->hi = t>>31;
if(b >= 64) {
/* this is illegal re C standard */
r->lo = t>>31;
return;
}
r->lo = t >> (b-32);
return;
}
if(b <= 0) {
r->hi = t;
r->lo = a.lo;
return;
}
r->hi = t >> b;
r->lo = (t << (32-b)) | (a.lo >> b);
}
void
_rshlv(Vlong *r, Vlong a, int b)
{
ulong t;
t = a.hi;
if(b >= 32) {
r->hi = 0;
if(b >= 64) {
/* this is illegal re C standard */
r->lo = 0;
return;
}
r->lo = t >> (b-32);
return;
}
if(b <= 0) {
r->hi = t;
r->lo = a.lo;
return;
}
r->hi = t >> b;
r->lo = (t << (32-b)) | (a.lo >> b);
}
void
_lshv(Vlong *r, Vlong a, int b)
{
ulong t;
t = a.lo;
if(b >= 32) {
r->lo = 0;
if(b >= 64) {
/* this is illegal re C standard */
r->hi = 0;
return;
}
r->hi = t << (b-32);
return;
}
if(b <= 0) {
r->lo = t;
r->hi = a.hi;
return;
}
r->lo = t << b;
r->hi = (t >> (32-b)) | (a.hi << b);
}
void
_andv(Vlong *r, Vlong a, Vlong b)
{
r->hi = a.hi & b.hi;
r->lo = a.lo & b.lo;
}
void
_orv(Vlong *r, Vlong a, Vlong b)
{
r->hi = a.hi | b.hi;
r->lo = a.lo | b.lo;
}
void
_xorv(Vlong *r, Vlong a, Vlong b)
{
r->hi = a.hi ^ b.hi;
r->lo = a.lo ^ b.lo;
}
void
_vpp(Vlong *l, Vlong *r)
{
l->hi = r->hi;
l->lo = r->lo;
r->lo++;
if(r->lo == 0)
r->hi++;
}
void
_vmm(Vlong *l, Vlong *r)
{
l->hi = r->hi;
l->lo = r->lo;
if(r->lo == 0)
r->hi--;
r->lo--;
}
void
_ppv(Vlong *l, Vlong *r)
{
r->lo++;
if(r->lo == 0)
r->hi++;
l->hi = r->hi;
l->lo = r->lo;
}
void
_mmv(Vlong *l, Vlong *r)
{
if(r->lo == 0)
r->hi--;
r->lo--;
l->hi = r->hi;
l->lo = r->lo;
}
void
_vasop(Vlong *ret, void *lv, void fn(Vlong*, Vlong, Vlong), int type, Vlong rv)
{
Vlong t, u;
u = *ret;
switch(type) {
default:
abort();
break;
case 1: /* schar */
t.lo = *(schar*)lv;
t.hi = t.lo >> 31;
fn(&u, t, rv);
*(schar*)lv = u.lo;
break;
case 2: /* uchar */
t.lo = *(uchar*)lv;
t.hi = 0;
fn(&u, t, rv);
*(uchar*)lv = u.lo;
break;
case 3: /* short */
t.lo = *(short*)lv;
t.hi = t.lo >> 31;
fn(&u, t, rv);
*(short*)lv = u.lo;
break;
case 4: /* ushort */
t.lo = *(ushort*)lv;
t.hi = 0;
fn(&u, t, rv);
*(ushort*)lv = u.lo;
break;
case 9: /* int */
t.lo = *(int*)lv;
t.hi = t.lo >> 31;
fn(&u, t, rv);
*(int*)lv = u.lo;
break;
case 10: /* uint */
t.lo = *(uint*)lv;
t.hi = 0;
fn(&u, t, rv);
*(uint*)lv = u.lo;
break;
case 5: /* long */
t.lo = *(long*)lv;
t.hi = t.lo >> 31;
fn(&u, t, rv);
*(long*)lv = u.lo;
break;
case 6: /* ulong */
t.lo = *(ulong*)lv;
t.hi = 0;
fn(&u, t, rv);
*(ulong*)lv = u.lo;
break;
case 7: /* vlong */
case 8: /* uvlong */
fn(&u, *(Vlong*)lv, rv);
*(Vlong*)lv = u;
break;
}
*ret = u;
}
void
_p2v(Vlong *ret, void *p)
{
long t;
t = (ulong)p;
ret->lo = t;
ret->hi = 0;
}
void
_sl2v(Vlong *ret, long sl)
{
long t;
t = sl;
ret->lo = t;
ret->hi = t >> 31;
}
void
_ul2v(Vlong *ret, ulong ul)
{
long t;
t = ul;
ret->lo = t;
ret->hi = 0;
}
void
_si2v(Vlong *ret, int si)
{
long t;
t = si;
ret->lo = t;
ret->hi = t >> 31;
}
void
_ui2v(Vlong *ret, uint ui)
{
long t;
t = ui;
ret->lo = t;
ret->hi = 0;
}
void
_sh2v(Vlong *ret, long sh)
{
long t;
t = (sh << 16) >> 16;
ret->lo = t;
ret->hi = t >> 31;
}
void
_uh2v(Vlong *ret, ulong ul)
{
long t;
t = ul & 0xffff;
ret->lo = t;
ret->hi = 0;
}
void
_sc2v(Vlong *ret, long uc)
{
long t;
t = (uc << 24) >> 24;
ret->lo = t;
ret->hi = t >> 31;
}
void
_uc2v(Vlong *ret, ulong ul)
{
long t;
t = ul & 0xff;
ret->lo = t;
ret->hi = 0;
}
long
_v2sc(Vlong rv)
{
long t;
t = rv.lo & 0xff;
return (t << 24) >> 24;
}
long
_v2uc(Vlong rv)
{
return rv.lo & 0xff;
}
long
_v2sh(Vlong rv)
{
long t;
t = rv.lo & 0xffff;
return (t << 16) >> 16;
}
long
_v2uh(Vlong rv)
{
return rv.lo & 0xffff;
}
long
_v2sl(Vlong rv)
{
return rv.lo;
}
long
_v2ul(Vlong rv)
{
return rv.lo;
}
long
_v2si(Vlong rv)
{
return rv.lo;
}
long
_v2ui(Vlong rv)
{
return rv.lo;
}
int
_testv(Vlong rv)
{
return rv.lo || rv.hi;
}
int
_eqv(Vlong lv, Vlong rv)
{
return lv.lo == rv.lo && lv.hi == rv.hi;
}
int
_nev(Vlong lv, Vlong rv)
{
return lv.lo != rv.lo || lv.hi != rv.hi;
}
int
_ltv(Vlong lv, Vlong rv)
{
return (long)lv.hi < (long)rv.hi ||
(lv.hi == rv.hi && lv.lo < rv.lo);
}
int
_lev(Vlong lv, Vlong rv)
{
return (long)lv.hi < (long)rv.hi ||
(lv.hi == rv.hi && lv.lo <= rv.lo);
}
int
_gtv(Vlong lv, Vlong rv)
{
return (long)lv.hi > (long)rv.hi ||
(lv.hi == rv.hi && lv.lo > rv.lo);
}
int
_gev(Vlong lv, Vlong rv)
{
return (long)lv.hi > (long)rv.hi ||
(lv.hi == rv.hi && lv.lo >= rv.lo);
}
int
_lov(Vlong lv, Vlong rv)
{
return lv.hi < rv.hi ||
(lv.hi == rv.hi && lv.lo < rv.lo);
}
int
_lsv(Vlong lv, Vlong rv)
{
return lv.hi < rv.hi ||
(lv.hi == rv.hi && lv.lo <= rv.lo);
}
int
_hiv(Vlong lv, Vlong rv)
{
return lv.hi > rv.hi ||
(lv.hi == rv.hi && lv.lo > rv.lo);
}
int
_hsv(Vlong lv, Vlong rv)
{
return lv.hi > rv.hi ||
(lv.hi == rv.hi && lv.lo >= rv.lo);
}

View File

@ -2,3 +2,103 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "runtime.h"
#include "defs.h"
#include "signals.h"
#include "os.h"
void dumpregs(void) {}
// void
// dumpregs(Sigcontext *r)
// {
// printf("eax %X\n", r->eax);
// printf("ebx %X\n", r->ebx);
// printf("ecx %X\n", r->ecx);
// printf("edx %X\n", r->edx);
// printf("edi %X\n", r->edi);
// printf("esi %X\n", r->esi);
// printf("ebp %X\n", r->ebp);
// printf("esp %X\n", r->esp);
// printf("eip %X\n", r->eip);
// printf("eflags %X\n", r->eflags);
// printf("cs %X\n", r->cs);
// printf("fs %X\n", r->fs);
// printf("gs %X\n", r->gs);
// }
/*
* This assembler routine takes the args from registers, puts them on the stack,
* and calls sighandler().
*/
extern void sigtramp(void);
extern void sigignore(void); // just returns
extern void sigreturn(void); // calls sigreturn
void sighandler(void) {}
// void
// sighandler(int32 sig, Siginfo* info, void* context)
// {
// Ucontext *uc;
// Sigcontext *sc;
// if(panicking) // traceback already printed
// exit(2);
// panicking = 1;
// uc = context;
// sc = &uc->uc_mcontext;
// if(sig < 0 || sig >= NSIG)
// printf("Signal %d\n", sig);
// else
// printf("%s\n", sigtab[sig].name);
// printf("Faulting address: %p\n", *(void**)info->_sifields);
// printf("pc=%X\n", sc->eip);
// printf("\n");
// if(gotraceback()){
// traceback((void*)sc->eip, (void*)sc->esp, m->curg);
// tracebackothers(m->curg);
// dumpregs(sc);
// }
// breakpoint();
// exit(2);
// }
void
signalstack(byte *p, int32 n)
{
// Sigaltstack st;
// st.ss_sp = p;
// st.ss_size = n;
// st.ss_flags = 0;
// sigaltstack(&st, nil);
}
void
initsig(void)
{
// static Sigaction sa;
// int32 i;
// sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER;
// sa.sa_mask = 0xFFFFFFFFFFFFFFFFULL;
// sa.sa_restorer = (void*)sigreturn;
// for(i = 0; i<NSIG; i++) {
// if(sigtab[i].flags) {
// if(sigtab[i].flags & SigCatch)
// *(void**)sa._u = (void*)sigtramp; // handler
// else
// *(void**)sa._u = (void*)sigignore; // handler
// if(sigtab[i].flags & SigRestart)
// sa.sa_flags |= SA_RESTART;
// else
// sa.sa_flags &= ~SA_RESTART;
// rt_sigaction(i, &sa, nil, 8);
// }
// }
}

View File

@ -7,9 +7,31 @@
//
TEXT write(SB),7,$0
MOVW 4(SP), R0
MOVW 8(SP), R1
MOVW 12(SP), R2
SWI $0x00900004 // syscall write
RET
TEXT exit(SB),7,$0
SWI $0x00900001 // exit value in R0
TEXT sys·write(SB),7,$0
MOVW 8(SP), R1
MOVW 12(SP), R2
SWI $0x00900004 // syscall write
RET
TEXT sys·mmap(SB),7,$0
BL abort(SB)
RET
// int64 futex(int32 *uaddr, int32 op, int32 val,
// struct timespec *timeout, int32 *uaddr2, int32 val2);
TEXT futex(SB),7,$0
BL abort(SB)
RET
// int64 clone(int32 flags, void *stack, M *m, G *g, void (*fn)(void));
TEXT clone(SB),7,$0
BL abort(SB)
RET