]> Cypherpunks repositories - gostls13.git/commitdiff
Break runtime.c into separate pieces for maps, strings, print, etc.
authorRob Pike <r@golang.org>
Mon, 30 Jun 2008 18:50:36 +0000 (11:50 -0700)
committerRob Pike <r@golang.org>
Mon, 30 Jun 2008 18:50:36 +0000 (11:50 -0700)
Share common assembler for amd64 runtime

SVN=125317

src/runtime/Makefile
src/runtime/rt0_amd64.s [new file with mode: 0644]
src/runtime/rt0_amd64_darwin.s
src/runtime/rt0_amd64_linux.s
src/runtime/runtime.c
src/runtime/runtime.h
src/runtime/runtime_map.c [new file with mode: 0644]
src/runtime/runtime_print.c [new file with mode: 0644]
src/runtime/runtime_string.c [new file with mode: 0644]
src/runtime/sys_amd64_darwin.s [new file with mode: 0644]
src/runtime/sys_amd64_linux.s [new file with mode: 0644]

index 2e51fa05b3bdcff7030cf1713b45a370c776422d..8b80e3f01df23738f87485770d5aea2c63152bc3 100644 (file)
@@ -13,9 +13,14 @@ RT0OFILES=\
        rt0_$(GOARCH)_$(GOOS).$O\
 
 LIBOFILES=\
+       rt0_$(GOARCH).$O\
        rt1_$(GOARCH)_$(GOOS).$O\
        rt2_$(GOARCH).$O\
+       sys_$(GOARCH)_$(GOOS).$O\
        runtime.$O\
+       runtime_map.$O\
+       runtime_print.$O\
+       runtime_string.$O\
        sys_file.$O\
 
 OFILES=$(RT0OFILES) $(LIBOFILES)
diff --git a/src/runtime/rt0_amd64.s b/src/runtime/rt0_amd64.s
new file mode 100644 (file)
index 0000000..18559eb
--- /dev/null
@@ -0,0 +1,181 @@
+// 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.
+
+
+TEXT   _rt0_amd64(SB),7,$-8
+
+       // copy arguments forward on an even stack
+
+       MOVQ    0(SP), AX               // argc
+       LEAQ    8(SP), BX               // argv
+       SUBQ    $(4*8+7), SP            // 2args 2auto
+       ANDQ    $~7, SP
+       MOVQ    AX, 16(SP)
+       MOVQ    BX, 24(SP)
+
+       // allocate the per-user block
+
+       LEAQ    peruser<>(SB), R15      // dedicated u. register
+
+       LEAQ    (-4096+104+4*8)(SP), AX
+       MOVQ    AX, 0(R15)              // 0(R15) is stack limit (w 104b guard)
+
+       MOVL    $1024, AX
+       MOVL    AX, 0(SP)
+       CALL    mal(SB)
+
+       LEAQ    104(AX), BX
+       MOVQ    BX, 16(R15)             // 16(R15) is limit of istack (w 104b guard)
+
+       ADDQ    0(SP), AX
+       LEAQ    (-4*8)(AX), BX
+       MOVQ    BX, 24(R15)             // 24(R15) is base of istack (w auto*4)
+
+       CALL    check(SB)
+
+       // process the arguments
+
+       MOVL    16(SP), AX              // copy argc
+       MOVL    AX, 0(SP)
+       MOVQ    24(SP), AX              // copy argv
+       MOVQ    AX, 8(SP)
+       CALL    args(SB)
+
+       CALL    main·main(SB)
+
+       MOVQ    $0, AX
+       MOVQ    AX, 0(SP)               // exit status
+       CALL    sys·exit(SB)
+
+       CALL    notok(SB)               // fault
+       RET
+
+//
+// the calling sequence for a routine that
+// needs N bytes stack, A args.
+//
+//     N1 = (N+160 > 4096)? N+160: 0
+//     A1 = A
+//
+// if N <= 75
+//     CMPQ    SP, 0(R15)
+//     JHI     3(PC)
+//     MOVQ    $(N1<<0) | (A1<<32)), AX
+//     CALL    _morestack
+//
+// if N > 75
+//     LEAQ    (-N-75)(SP), AX
+//     CMPQ    AX, 0(R15)
+//     JHI     3(PC)
+//     MOVQ    $(N1<<0) | (A1<<32)), AX
+//     CALL    _morestack
+//
+
+TEXT   _morestack(SB), 7, $0
+       // save stuff on interrupt stack
+
+       MOVQ    24(R15), BX             // istack
+       MOVQ    SP, 8(BX)               // old SP
+       MOVQ    AX, 16(BX)              // magic number
+       MOVQ    0(R15), AX              // old limit
+       MOVQ    AX, 24(BX)
+
+       // switch and set up new limit
+
+       MOVQ    BX, SP
+       MOVQ    16(R15), AX             // istack limit
+       MOVQ    AX, 0(R15)
+
+       // allocate a new stack max of request and 4k
+
+       MOVL    16(SP), AX              // magic number
+       CMPL    AX, $4096
+       JHI     2(PC)
+       MOVL    $4096, AX
+       MOVL    AX, 0(SP)
+       CALL    mal(SB)
+
+       // switch to new stack
+
+       MOVQ    SP, BX                  // istack
+       ADDQ    $104, AX                // new stack limit
+       MOVQ    AX, 0(R15)
+       ADDQ    0(SP), AX
+       LEAQ    (-104-4*8)(AX), SP      // new SP
+       MOVQ    8(R15), AX
+       MOVQ    AX, 0(SP)               // old base
+       MOVQ    SP, 8(R15)              // new base
+
+       // copy needed stuff from istack to new stack
+
+       MOVQ    16(BX), AX              // magic number
+       MOVQ    AX, 16(SP)
+       MOVQ    24(BX), AX              // old limit
+       MOVQ    AX, 24(SP)
+       MOVQ    8(BX), AX               // old SP
+       MOVQ    AX, 8(SP)
+
+// are there parameters
+
+       MOVL    20(SP), CX              // copy count
+       CMPL    CX, $0
+       JEQ     easy
+
+// copy in
+
+       LEAQ    16(AX), SI
+       SUBQ    CX, SP
+       MOVQ    SP, DI
+       SHRL    $3, CX
+       CLD
+       REP
+       MOVSQ
+
+       // call the intended
+       CALL    0(AX)
+
+// copy out
+
+       MOVQ    SP, SI
+       MOVQ    8(R15), BX              // new base
+       MOVQ    8(BX), AX               // old SP
+       LEAQ    16(AX), DI
+       MOVL    20(BX), CX              // copy count
+       SHRL    $3, CX
+       CLD
+       REP
+       MOVSQ
+
+       // restore old SP and limit
+       MOVQ    8(R15), SP              // new base
+       MOVQ    24(SP), AX              // old limit
+       MOVQ    AX, 0(R15)
+       MOVQ    0(SP), AX
+       MOVQ    AX, 8(R15)              // old base
+       MOVQ    8(SP), AX               // old SP
+       MOVQ    AX, SP
+
+       // and return to the call behind mine
+       ADDQ    $8, SP
+       RET
+
+easy:
+       CALL    0(AX)
+
+       // restore old SP and limit
+       MOVQ    24(SP), AX              // old limit
+       MOVQ    AX, 0(R15)
+       MOVQ    0(SP), AX
+       MOVQ    AX, 8(R15)              // old base
+       MOVQ    8(SP), AX               // old SP
+       MOVQ    AX, SP
+
+       // and return to the call behind mine
+       ADDQ    $8, SP
+       RET
+
+TEXT   FLUSH(SB),7,$-8
+       RET
+
+GLOBL  peruser<>(SB),$64
index 8f2aed6696ed06feba9587a9d2111069264db076..0a0011781dbb18792c03ef68073a993eb288bea0 100644 (file)
@@ -2,283 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Darwin and Linux use the same linkage to main
 
 TEXT   _rt0_amd64_darwin(SB),7,$-8
-
-       // copy arguments forward on an even stack
-
-       MOVQ    0(SP), AX               // argc
-       LEAQ    8(SP), BX               // argv
-       SUBQ    $(4*8+7), SP            // 2args 2auto
-       ANDQ    $~7, SP
-       MOVQ    AX, 16(SP)
-       MOVQ    BX, 24(SP)
-
-       // allocate the per-user block
-
-       LEAQ    peruser<>(SB), R15      // dedicated u. register
-
-       LEAQ    (-4096+104+4*8)(SP), AX
-       MOVQ    AX, 0(R15)              // 0(R15) is stack limit (w 104b guard)
-
-       MOVL    $1024, AX
-       MOVL    AX, 0(SP)
-       CALL    mal(SB)
-
-       LEAQ    104(AX), BX
-       MOVQ    BX, 16(R15)             // 16(R15) is limit of istack (w 104b guard)
-
-       ADDQ    0(SP), AX
-       LEAQ    (-4*8)(AX), BX
-       MOVQ    BX, 24(R15)             // 24(R15) is base of istack (w auto*4)
-
-       CALL    check(SB)
-
-       // process the arguments
-
-       MOVL    16(SP), AX              // copy argc
-       MOVL    AX, 0(SP)
-       MOVQ    24(SP), AX              // copy argv
-       MOVQ    AX, 8(SP)
-       CALL    args(SB)
-
-       CALL    main·main(SB)
-
-       MOVQ    $0, AX
-       MOVQ    AX, 0(SP)               // exit status
-       CALL    sys·exit(SB)
-
-       CALL    notok(SB)               // fault
-       RET
-
-//
-// the calling sequence for a routine that
-// needs N bytes stack, A args.
-//
-//     N1 = (N+160 > 4096)? N+160: 0
-//     A1 = A
-//
-// if N <= 75
-//     CMPQ    SP, 0(R15)
-//     JHI     3(PC)
-//     MOVQ    $(N1<<0) | (A1<<32)), AX
-//     CALL    _morestack
-//
-// if N > 75
-//     LEAQ    (-N-75)(SP), AX
-//     CMPQ    AX, 0(R15)
-//     JHI     3(PC)
-//     MOVQ    $(N1<<0) | (A1<<32)), AX
-//     CALL    _morestack
-//
-
-TEXT   _morestack(SB), 7, $0
-       // save stuff on interrupt stack
-
-       MOVQ    24(R15), BX             // istack
-       MOVQ    SP, 8(BX)               // old SP
-       MOVQ    AX, 16(BX)              // magic number
-       MOVQ    0(R15), AX              // old limit
-       MOVQ    AX, 24(BX)
-
-       // switch and set up new limit
-
-       MOVQ    BX, SP
-       MOVQ    16(R15), AX             // istack limit
-       MOVQ    AX, 0(R15)
-
-       // allocate a new stack max of request and 4k
-
-       MOVL    16(SP), AX              // magic number
-       CMPL    AX, $4096
-       JHI     2(PC)
-       MOVL    $4096, AX
-       MOVL    AX, 0(SP)
-       CALL    mal(SB)
-
-       // switch to new stack
-
-       MOVQ    SP, BX                  // istack
-       ADDQ    $104, AX                // new stack limit
-       MOVQ    AX, 0(R15)
-       ADDQ    0(SP), AX
-       LEAQ    (-104-4*8)(AX), SP      // new SP
-       MOVQ    8(R15), AX
-       MOVQ    AX, 0(SP)               // old base
-       MOVQ    SP, 8(R15)              // new base
-
-       // copy needed stuff from istack to new stack
-
-       MOVQ    16(BX), AX              // magic number
-       MOVQ    AX, 16(SP)
-       MOVQ    24(BX), AX              // old limit
-       MOVQ    AX, 24(SP)
-       MOVQ    8(BX), AX               // old SP
-       MOVQ    AX, 8(SP)
-
-// are there parameters
-
-       MOVL    20(SP), CX              // copy count
-       CMPL    CX, $0
-       JEQ     easy
-
-// copy in
-
-       LEAQ    16(AX), SI
-       SUBQ    CX, SP
-       MOVQ    SP, DI
-       SHRL    $3, CX
-       CLD
-       REP
-       MOVSQ
-
-       // call the intended
-       CALL    0(AX)
-
-// copy out
-
-       MOVQ    SP, SI
-       MOVQ    8(R15), BX              // new base
-       MOVQ    8(BX), AX               // old SP
-       LEAQ    16(AX), DI
-       MOVL    20(BX), CX              // copy count
-       SHRL    $3, CX
-       CLD
-       REP
-       MOVSQ
-
-       // restore old SP and limit
-       MOVQ    8(R15), SP              // new base
-       MOVQ    24(SP), AX              // old limit
-       MOVQ    AX, 0(R15)
-       MOVQ    0(SP), AX
-       MOVQ    AX, 8(R15)              // old base
-       MOVQ    8(SP), AX               // old SP
-       MOVQ    AX, SP
-
-       // and return to the call behind mine
-       ADDQ    $8, SP
-       RET
-
-easy:
-       CALL    0(AX)
-
-       // restore old SP and limit
-       MOVQ    24(SP), AX              // old limit
-       MOVQ    AX, 0(R15)
-       MOVQ    0(SP), AX
-       MOVQ    AX, 8(R15)              // old base
-       MOVQ    8(SP), AX               // old SP
-       MOVQ    AX, SP
-
-       // and return to the call behind mine
-       ADDQ    $8, SP
-       RET
-
-TEXT   FLUSH(SB),7,$-8
-       RET
-
-TEXT   sys·exit(SB),1,$-8
-       MOVL    8(SP), DI               // arg 1 exit status
-       MOVL    $(0x2000000+1), AX      // syscall entry
-       SYSCALL
-       CALL    notok(SB)
-       RET
-
-TEXT   sys·write(SB),1,$-8
-       MOVL    8(SP), DI               // arg 1 fid
-       MOVQ    16(SP), SI              // arg 2 buf
-       MOVL    24(SP), DX              // arg 3 count
-       MOVL    $(0x2000000+4), AX      // syscall entry
-       SYSCALL
-       JCC     2(PC)
-       CALL    notok(SB)
-       RET
-
-TEXT   open(SB),1,$-8
-       MOVQ    8(SP), DI
-       MOVL    16(SP), SI
-       MOVQ    $0, R10
-       MOVL    $(0x2000000+5), AX      // syscall entry
-       SYSCALL
-       RET
-
-TEXT   close(SB),1,$-8
-       MOVL    8(SP), DI
-       MOVL    $(0x2000000+6), AX      // syscall entry
-       SYSCALL
-       RET
-
-TEXT   fstat(SB),1,$-8
-       MOVL    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVL    $(0x2000000+339), AX    // syscall entry; really fstat64
-       SYSCALL
-       RET
-
-TEXT   read(SB),1,$-8
-       MOVL    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVL    24(SP), DX
-       MOVL    $(0x2000000+3), AX      // syscall entry
-       SYSCALL
-       RET
-
-TEXT   sys·sigaction(SB),1,$-8
-       MOVL    8(SP), DI               // arg 1 sig
-       MOVQ    16(SP), SI              // arg 2 act
-       MOVQ    24(SP), DX              // arg 3 oact
-       MOVQ    24(SP), CX              // arg 3 oact
-       MOVQ    24(SP), R10             // arg 3 oact
-       MOVL    $(0x2000000+46), AX     // syscall entry
-       SYSCALL
-       JCC     2(PC)
-       CALL    notok(SB)
-       RET
-
-TEXT sigtramp(SB),1,$24
-       MOVL    DX,0(SP)
-       MOVQ    CX,8(SP)
-       MOVQ    R8,16(SP)
-       CALL    sighandler(SB)
-       RET
-
-TEXT   sys·breakpoint(SB),1,$-8
-       BYTE    $0xcc
-       RET
-
-TEXT   sys·mmap(SB),1,$-8
-       MOVQ    8(SP), DI               // arg 1 addr
-       MOVL    16(SP), SI              // arg 2 len
-       MOVL    20(SP), DX              // arg 3 prot
-       MOVL    24(SP), R10             // arg 4 flags
-       MOVL    28(SP), R8              // arg 5 fid
-       MOVL    32(SP), R9              // arg 6 offset
-       MOVL    $(0x2000000+197), AX    // syscall entry
-       SYSCALL
-       JCC     2(PC)
-       CALL    notok(SB)
-       RET
-
-TEXT   notok(SB),1,$-8
-       MOVL    $0xf1, BP
-       MOVQ    BP, (BP)
-       RET
-
-TEXT   sys·memclr(SB),1,$-8
-       MOVQ    8(SP), DI               // arg 1 addr
-       MOVL    16(SP), CX              // arg 2 count
-       ADDL    $7, CX
-       SHRL    $3, CX
-       MOVQ    $0, AX
-       CLD
-       REP
-       STOSQ
-       RET
-
-TEXT   sys·getcallerpc+0(SB),1,$0
-       MOVQ    x+0(FP),AX
-       MOVQ    -8(AX),AX
-       RET
-
-GLOBL  peruser<>(SB),$64
+       MOVQ    $_rt0_amd64(SB), AX
+       JMP     AX
index fdda7e1c8eee769a1cd7ca667033ff842dd9a4c1..55be5bceef01ee1c1b135eb19403ddc2470fe776 100644 (file)
@@ -2,287 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Darwin and Linux use the same linkage to main
 
 TEXT   _rt0_amd64_linux(SB),7,$-8
-
-       // copy arguments forward on an even stack
-
-       MOVQ    0(SP), AX               // argc
-       LEAQ    8(SP), BX               // argv
-       SUBQ    $(4*8+7), SP            // 2args 2auto
-       ANDQ    $~7, SP
-       MOVQ    AX, 16(SP)
-       MOVQ    BX, 24(SP)
-
-       // allocate the per-user block
-
-       LEAQ    peruser<>(SB), R15      // dedicated u. register
-
-       LEAQ    (-4096+104+4*8)(SP), AX
-       MOVQ    AX, 0(R15)              // 0(R15) is stack limit (w 104b guard)
-
-       MOVL    $1024, AX
-       MOVL    AX, 0(SP)
-       CALL    mal(SB)
-
-       LEAQ    104(AX), BX
-       MOVQ    BX, 16(R15)             // 16(R15) is limit of istack (w 104b guard)
-
-       ADDQ    0(SP), AX
-       LEAQ    (-4*8)(AX), BX
-       MOVQ    BX, 24(R15)             // 24(R15) is base of istack (w auto*4)
-
-       CALL    check(SB)
-
-       // process the arguments
-
-       MOVL    16(SP), AX              // copy argc
-       MOVL    AX, 0(SP)
-       MOVQ    24(SP), AX              // copy argv
-       MOVQ    AX, 8(SP)
-       CALL    args(SB)
-
-       CALL    main·main(SB)
-
-       MOVQ    $0, AX
-       MOVQ    AX, 0(SP)               // exit status
-       CALL    sys·exit(SB)
-
-       CALL    notok(SB)               // fault
-       RET
-
-//
-// the calling sequence for a routine that
-// needs N bytes stack, A args.
-//
-//     N1 = (N+160 > 4096)? N+160: 0
-//     A1 = A
-//
-// if N <= 75
-//     CMPQ    SP, 0(R15)
-//     JHI     3(PC)
-//     MOVQ    $(N1<<0) | (A1<<32)), AX
-//     CALL    _morestack
-//
-// if N > 75
-//     LEAQ    (-N-75)(SP), AX
-//     CMPQ    AX, 0(R15)
-//     JHI     3(PC)
-//     MOVQ    $(N1<<0) | (A1<<32)), AX
-//     CALL    _morestack
-//
-
-TEXT   _morestack(SB), 7, $0
-       // save stuff on interrupt stack
-
-       MOVQ    24(R15), BX             // istack
-       MOVQ    SP, 8(BX)               // old SP
-       MOVQ    AX, 16(BX)              // magic number
-       MOVQ    0(R15), AX              // old limit
-       MOVQ    AX, 24(BX)
-
-       // switch and set up new limit
-
-       MOVQ    BX, SP
-       MOVQ    16(R15), AX             // istack limit
-       MOVQ    AX, 0(R15)
-
-       // allocate a new stack max of request and 4k
-
-       MOVL    16(SP), AX              // magic number
-       CMPL    AX, $4096
-       JHI     2(PC)
-       MOVL    $4096, AX
-       MOVL    AX, 0(SP)
-       CALL    mal(SB)
-
-       // switch to new stack
-
-       MOVQ    SP, BX                  // istack
-       ADDQ    $104, AX                // new stack limit
-       MOVQ    AX, 0(R15)
-       ADDQ    0(SP), AX
-       LEAQ    (-104-4*8)(AX), SP      // new SP
-       MOVQ    8(R15), AX
-       MOVQ    AX, 0(SP)               // old base
-       MOVQ    SP, 8(R15)              // new base
-
-       // copy needed stuff from istack to new stack
-
-       MOVQ    16(BX), AX              // magic number
-       MOVQ    AX, 16(SP)
-       MOVQ    24(BX), AX              // old limit
-       MOVQ    AX, 24(SP)
-       MOVQ    8(BX), AX               // old SP
-       MOVQ    AX, 8(SP)
-
-// are there parameters
-
-       MOVL    20(SP), CX              // copy count
-       CMPL    CX, $0
-       JEQ     easy
-
-// copy in
-
-       LEAQ    16(AX), SI
-       SUBQ    CX, SP
-       MOVQ    SP, DI
-       SHRL    $3, CX
-       CLD
-       REP
-       MOVSQ
-
-       // call the intended
-       CALL    0(AX)
-
-// copy out
-
-       MOVQ    SP, SI
-       MOVQ    8(R15), BX              // new base
-       MOVQ    8(BX), AX               // old SP
-       LEAQ    16(AX), DI
-       MOVL    20(BX), CX              // copy count
-       SHRL    $3, CX
-       CLD
-       REP
-       MOVSQ
-
-       // restore old SP and limit
-       MOVQ    8(R15), SP              // new base
-       MOVQ    24(SP), AX              // old limit
-       MOVQ    AX, 0(R15)
-       MOVQ    0(SP), AX
-       MOVQ    AX, 8(R15)              // old base
-       MOVQ    8(SP), AX               // old SP
-       MOVQ    AX, SP
-
-       // and return to the call behind mine
-       ADDQ    $8, SP
-       RET
-
-easy:
-       CALL    0(AX)
-
-       // restore old SP and limit
-       MOVQ    24(SP), AX              // old limit
-       MOVQ    AX, 0(R15)
-       MOVQ    0(SP), AX
-       MOVQ    AX, 8(R15)              // old base
-       MOVQ    8(SP), AX               // old SP
-       MOVQ    AX, SP
-
-       // and return to the call behind mine
-       ADDQ    $8, SP
-       RET
-
-TEXT   FLUSH(SB),7,$-8
-       RET
-
-TEXT   sys·exit(SB),1,$-8
-       MOVL    8(SP), DI
-       MOVL    $60, AX
-       SYSCALL
-       RET
-
-TEXT   sys·write(SB),1,$-8
-       MOVL    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVL    24(SP), DX
-       MOVL    $1, AX                  // syscall entry
-       SYSCALL
-       RET
-
-TEXT   open(SB),1,$-8
-       MOVQ    8(SP), DI
-       MOVL    16(SP), SI
-       MOVL    $2, AX                  // syscall entry
-       SYSCALL
-       RET
-
-TEXT   close(SB),1,$-8
-       MOVL    8(SP), DI
-       MOVL    $3, AX                  // syscall entry
-       SYSCALL
-       RET
-
-TEXT   fstat(SB),1,$-8
-       MOVL    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVL    $5, AX                  // syscall entry
-       SYSCALL
-       RET
-
-TEXT   read(SB),1,$-8
-       MOVL    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVL    24(SP), DX
-       MOVL    $0, AX                  // syscall entry
-       SYSCALL
-       RET
-
-TEXT   sys·rt_sigaction(SB),1,$-8
-       MOVL    8(SP), DI
-       MOVQ    16(SP), SI
-       MOVQ    24(SP), DX
-       MOVQ    32(SP), CX
-       MOVL    CX, R10
-       MOVL    $13, AX                 // syscall entry
-       SYSCALL
-       RET
-
-TEXT   sigtramp(SB),1,$24
-       MOVQ    DI,0(SP)
-       MOVQ    SI,8(SP)
-       MOVQ    DX,16(SP)
-       CALL    sighandler(SB)
-       RET
-
-TEXT   sys·breakpoint(SB),1,$-8
-       BYTE    $0xcc
-       RET
-
-TEXT   sys·mmap(SB),1,$-8
-       MOVQ    8(SP), DI
-       MOVL    16(SP), SI
-       MOVL    20(SP), DX
-       MOVL    24(SP), CX
-       MOVL    28(SP), R8
-       MOVL    32(SP), R9
-
-/* flags arg for ANON is 1000 but sb 20 */
-       MOVL    CX, AX
-       ANDL    $~0x1000, CX
-       ANDL    $0x1000, AX
-       SHRL    $7, AX
-       ORL     AX, CX
-
-       MOVL    CX, R10
-       MOVL    $9, AX                  // syscall entry
-       SYSCALL
-       CMPQ    AX, $0xfffffffffffff001
-       JLS     2(PC)
-       CALL    notok(SB)
-       RET
-
-TEXT   notok(SB),1,$-8
-       MOVL    $0xf1, BP
-       MOVQ    BP, (BP)
-       RET
-
-TEXT   sys·memclr(SB),1,$-8
-       MOVQ    8(SP), DI               // arg 1 addr
-       MOVL    16(SP), CX              // arg 2 count (cannot be zero)
-       ADDL    $7, CX
-       SHRL    $3, CX
-       MOVQ    $0, AX
-       CLD
-       REP
-       STOSQ
-       RET
-
-TEXT   sys·getcallerpc+0(SB),1,$0
-       MOVQ    x+0(FP),AX
-       MOVQ    -8(AX),AX
-       RET
-
-GLOBL  peruser<>(SB),$64
+       MOVQ    $_rt0_amd64(SB), AX
+       JMP     AX
index 52ffba7d880f7c6a04188d5b7c6b66bd05f1cde8..f1d7fc385e3b84ce9b59657e66e1fc6890f0afec 100644 (file)
@@ -6,103 +6,6 @@
 
 int32  debug   = 0;
 
-static int32   empty           = 0;
-static string  emptystring     = (string)&empty;
-
-void
-sys·printbool(bool v)
-{
-       if(v) {
-               sys·write(1, (byte*)"true", 4);
-               return;
-       }
-       sys·write(1, (byte*)"false", 5);
-}
-
-void
-sys·printfloat(float64 v)
-{
-       sys·write(1, "printfloat", 10);
-}
-
-void
-sys·printint(int64 v)
-{
-       byte buf[100];
-       int32 i, s;
-
-       s = 0;
-       if(v < 0) {
-               v = -v;
-               s = 1;
-               if(v < 0) {
-                       sys·write(1, (byte*)"-oo", 3);
-                       return;
-               }
-       }
-
-       for(i=nelem(buf)-1; i>0; i--) {
-               buf[i] = v%10 + '0';
-               if(v < 10)
-                       break;
-               v = v/10;
-       }
-       if(s) {
-               i--;
-               buf[i] = '-';
-       }
-       sys·write(1, buf+i, nelem(buf)-i);
-}
-
-void
-sys·printpointer(void *p)
-{
-       uint64 v;
-       byte buf[100];
-       int32 i;
-
-       v = (int64)p;
-       for(i=nelem(buf)-1; i>0; i--) {
-               buf[i] = v%16 + '0';
-               if(buf[i] > '9')
-                       buf[i] += 'a'-'0'-10;
-               if(v < 16)
-                       break;
-               v = v/16;
-       }
-       sys·write(1, buf+i, nelem(buf)-i);
-}
-
-void
-sys·printstring(string v)
-{
-       if(v != nil)
-               sys·write(1, v->str, v->len);
-}
-
-int32
-findnull(int8 *s)
-{
-       int32 l;
-
-       for(l=0; s[l]!=0; l++)
-               ;
-       return l;
-}
-
-void
-prints(int8 *s)
-{
-       sys·write(1, s, findnull(s));
-}
-
-void
-sys·printpc(void *p)
-{
-       prints("PC=0x");
-       sys·printpointer(sys·getcallerpc(p));
-}
-
 /*BUG: move traceback code to architecture-dependent runtime */
 void
 sys·panicl(int32 lno)
@@ -120,23 +23,6 @@ sys·panicl(int32 lno)
        sys·exit(2);
 }
 
-dump(byte *p, int32 n)
-{
-       uint32 v;
-       int32 i;
-
-       for(i=0; i<n; i++) {
-               sys·printpointer((byte*)(p[i]>>4));
-               sys·printpointer((byte*)(p[i]&0xf));
-               if((i&15) == 15)
-                       prints("\n");
-               else
-                       prints(" ");
-       }
-       if(n & 15)
-               prints("\n");
-}
-
 static uint8*  hunk;
 static uint32  nhunk;
 static uint64  nmmap;
@@ -217,1033 +103,9 @@ mal(uint32 n)
        return v;
 }
 
-uint32
-cmpstring(string s1, string s2)
-{
-       uint32 i, l;
-       byte c1, c2;
-
-       if(s1 == nil)
-               s1 = emptystring;
-       if(s2 == nil)
-               s2 = emptystring;
-
-       l = s1->len;
-       if(s2->len < l)
-               l = s2->len;
-       for(i=0; i<l; i++) {
-               c1 = s1->str[i];
-               c2 = s2->str[i];
-               if(c1 < c2)
-                       return -1;
-               if(c1 > c2)
-                       return +1;
-       }
-       if(s1->len < s2->len)
-               return -1;
-       if(s1->len > s2->len)
-               return +1;
-       return 0;
-}
-
 void
 sys·mal(uint32 n, uint8 *ret)
 {
        ret = mal(n);
        FLUSH(&ret);
 }
-
-void
-sys·catstring(string s1, string s2, string s3)
-{
-       uint32 l;
-
-       if(s1 == nil || s1->len == 0) {
-               s3 = s2;
-               goto out;
-       }
-       if(s2 == nil || s2->len == 0) {
-               s3 = s1;
-               goto out;
-       }
-
-       l = s1->len + s2->len;
-
-       s3 = mal(sizeof(s3->len)+l);
-       s3->len = l;
-       mcpy(s3->str, s1->str, s1->len);
-       mcpy(s3->str+s1->len, s2->str, s2->len);
-
-out:
-       FLUSH(&s3);
-}
-
-void
-sys·cmpstring(string s1, string s2, int32 v)
-{
-       v = cmpstring(s1, s2);
-       FLUSH(&v);
-}
-
-static int32
-strcmp(byte *s1, byte *s2)
-{
-       uint32 i;
-       byte c1, c2;
-
-       for(i=0;; i++) {
-               c1 = s1[i];
-               c2 = s2[i];
-               if(c1 < c2)
-                       return -1;
-               if(c1 > c2)
-                       return +1;
-               if(c1 == 0)
-                       return 0;
-       }
-}
-
-static void
-prbounds(int8* s, int32 a, int32 b, int32 c)
-{
-       int32 i;
-
-       prints(s);
-       prints(" ");
-       sys·printint(a);
-       prints("<");
-       sys·printint(b);
-       prints(">");
-       sys·printint(c);
-       prints("\n");
-       throw("bounds");
-}
-
-void
-sys·slicestring(string si, int32 lindex, int32 hindex, string so)
-{
-       string s, str;
-       int32 l;
-
-       if(si == nil)
-               si = emptystring;
-
-       if(lindex < 0 || lindex > si->len ||
-          hindex < lindex || hindex > si->len) {
-               sys·printpc(&si);
-               prints(" ");
-               prbounds("slice", lindex, si->len, hindex);
-       }
-
-       l = hindex-lindex;
-       so = mal(sizeof(so->len)+l);
-       so->len = l;
-       mcpy(so->str, si->str+lindex, l);
-       FLUSH(&so);
-}
-
-void
-sys·indexstring(string s, int32 i, byte b)
-{
-       if(s == nil)
-               s = emptystring;
-
-       if(i < 0 || i >= s->len) {
-               sys·printpc(&s);
-               prints(" ");
-               prbounds("index", 0, i, s->len);
-       }
-
-       b = s->str[i];
-       FLUSH(&b);
-}
-
-/*
- * this is the plan9 runetochar
- * extended for 36 bits in 7 bytes
- * note that it truncates to 32 bits
- * through the argument passing.
- */
-static int32
-runetochar(byte *str, uint32 c)
-{
-       int32 i, n;
-       uint32 mask, mark;
-
-       /*
-        * one character in 7 bits
-        */
-       if(c <= 0x07FUL) {
-               str[0] = c;
-               return 1;
-       }
-
-       /*
-        * every new character picks up 5 bits
-        * one less in the first byte and
-        * six more in an extension byte
-        */
-       mask = 0x7ffUL;
-       mark = 0xC0UL;
-       for(n=1;; n++) {
-               if(c <= mask)
-                       break;
-               mask = (mask<<5) | 0x1fUL;
-               mark = (mark>>1) | 0x80UL;
-       }
-
-       /*
-        * lay down the bytes backwards
-        * n is the number of extension bytes
-        * mask is the max codepoint
-        * mark is the zeroth byte indicator
-        */
-       for(i=n; i>0; i--) {
-               str[i] = 0x80UL | (c&0x3fUL);
-               c >>= 6;
-       }
-
-       str[0] = mark|c;
-       return n+1;
-}
-
-void
-sys·intstring(int64 v, string s)
-{
-       int32 l;
-
-       s = mal(sizeof(s->len)+8);
-       s->len = runetochar(s->str, v);
-       FLUSH(&s);
-}
-
-void
-sys·byteastring(byte *a, int32 l, string s)
-{
-       s = mal(sizeof(s->len)+l);
-       s->len = l;
-       mcpy(s->str, a, l);
-       FLUSH(&s);
-}
-
-static Map*    hash[1009];
-
-static Map*
-hashmap(Sigi *si, Sigs *ss)
-{
-       int32 ns, ni;
-       uint32 ihash, h;
-       byte *sname, *iname;
-       Map *m;
-
-       h = ((uint32)si + (uint32)ss) % nelem(hash);
-       for(m=hash[h]; m!=nil; m=m->link) {
-               if(m->si == si && m->ss == ss) {
-                       if(m->bad) {
-                               throw("bad hashmap");
-                               m = nil;
-                       }
-                       // prints("old hashmap\n");
-                       return m;
-               }
-       }
-
-       ni = si[0].offset;      // first word has size
-       m = mal(sizeof(*m) + ni*sizeof(m->fun[0]));
-       m->si = si;
-       m->ss = ss;
-
-       ni = 1;                 // skip first word
-       ns = 0;
-
-loop1:
-       // pick up next name from
-       // interface signature
-       iname = si[ni].name;
-       if(iname == nil) {
-               m->link = hash[h];
-               hash[h] = m;
-               // prints("new hashmap\n");
-               return m;
-       }
-       ihash = si[ni].hash;
-
-loop2:
-       // pick up and comapre next name
-       // from structure signature
-       sname = ss[ns].name;
-       if(sname == nil) {
-               prints((int8*)iname);
-               prints(": ");
-               throw("hashmap: failed to find method");
-               m->bad = 1;
-               m->link = hash[h];
-               hash[h] = m;
-               return nil;
-       }
-       if(ihash != ss[ns].hash ||
-          strcmp(sname, iname) != 0) {
-               ns++;
-               goto loop2;
-       }
-
-       m->fun[si[ni].offset] = ss[ns].fun;
-       ni++;
-       goto loop1;
-}
-
-void
-sys·ifaces2i(Sigi *si, Sigs *ss, Map *m, void *s)
-{
-
-       if(debug) {
-               prints("s2i sigi=");
-               sys·printpointer(si);
-               prints(" sigs=");
-               sys·printpointer(ss);
-               prints(" s=");
-               sys·printpointer(s);
-       }
-
-       if(s == nil) {
-               throw("ifaces2i: nil pointer");
-               m = nil;
-               FLUSH(&m);
-               return;
-       }
-
-       m = hashmap(si, ss);
-
-       if(debug) {
-               prints(" returning m=");
-               sys·printpointer(m);
-               prints(" s=");
-               sys·printpointer(s);
-               prints("\n");
-               dump((byte*)m, 64);
-       }
-
-       FLUSH(&m);
-}
-
-void
-sys·ifacei2i(Sigi *si, Map *m, void *s)
-{
-
-       if(debug) {
-               prints("i2i sigi=");
-               sys·printpointer(si);
-               prints(" m=");
-               sys·printpointer(m);
-               prints(" s=");
-               sys·printpointer(s);
-       }
-
-       if(m == nil) {
-               throw("ifacei2i: nil map");
-               s = nil;
-               FLUSH(&s);
-               return;
-       }
-
-       if(m->si == nil) {
-               throw("ifacei2i: nil pointer");
-               return;
-       }
-
-       if(m->si != si) {
-               m = hashmap(si, m->ss);
-               FLUSH(&m);
-       }
-
-       if(debug) {
-               prints(" returning m=");
-               sys·printpointer(m);
-               prints(" s=");
-               sys·printpointer(s);
-               prints("\n");
-               dump((byte*)m, 64);
-       }
-}
-
-void
-sys·ifacei2s(Sigs *ss, Map *m, void *s)
-{
-
-       if(debug) {
-               prints("i2s m=");
-               sys·printpointer(m);
-               prints(" s=");
-               sys·printpointer(s);
-               prints("\n");
-       }
-
-       if(m == nil) {
-               throw("ifacei2s: nil map");
-               s = nil;
-               FLUSH(&s);
-               return;
-       }
-
-       if(m->ss != ss) {
-               dump((byte*)m, 64);
-               throw("ifacei2s: wrong pointer");
-               s = nil;
-               FLUSH(&s);
-               return;
-       }
-}
-
-enum
-{
-       NANEXP          = 2047<<20,
-       NANMASK         = 2047<<20,
-       NANSIGN         = 1<<31,
-};
-
-static uint64  uvnan           = 0x7FF0000000000001;
-static uint64  uvinf           = 0x7FF0000000000000;
-static uint64  uvneginf        = 0xFFF0000000000000;
-
-static int32
-isInf(float64 d, int32 sign)
-{
-       uint64 x;
-
-       x = *(uint64*)&d;
-       if(sign == 0) {
-               if(x == uvinf || x == uvneginf)
-                       return 1;
-               return 0;
-       }
-       if(sign > 0) {
-               if(x == uvinf)
-                       return 1;
-               return 0;
-       }
-       if(x == uvneginf)
-               return 1;
-       return 0;
-}
-
-static float64
-NaN(void)
-{
-       return *(float64*)&uvnan;
-}
-
-static int32
-isNaN(float64 d)
-{
-       uint64 x;
-
-       x = *(uint64*)&d;
-       return ((uint32)x>>32)==0x7FF00000 && !isInf(d, 0);
-}
-
-static float64
-Inf(int32 sign)
-{
-       if(sign < 0)
-               return *(float64*)&uvinf;
-       else
-               return *(float64*)&uvneginf;
-}
-
-enum
-{
-       MASK    = 0x7ffL,
-       SHIFT   = 64-11-1,
-       BIAS    = 1022L,
-};
-
-static float64
-frexp(float64 d, int32 *ep)
-{
-       uint64 x;
-
-       if(d == 0) {
-               *ep = 0;
-               return 0;
-       }
-       x = *(uint64*)&d;
-       *ep = (int32)((x >> SHIFT) & MASK) - BIAS;
-       x &= ~((uint64)MASK << SHIFT);
-       x |= (uint64)BIAS << SHIFT;
-       return *(float64*)&x;
-}
-
-static float64
-ldexp(float64 d, int32 e)
-{
-       uint64 x;
-
-       if(d == 0)
-               return 0;
-       x = *(uint64*)&d;
-       e += (int32)(x >> SHIFT) & MASK;
-       if(e <= 0)
-               return 0;       /* underflow */
-       if(e >= MASK){          /* overflow */
-               if(d < 0)
-                       return Inf(-1);
-               return Inf(1);
-       }
-       x &= ~((uint64)MASK << SHIFT);
-       x |= (uint64)e << SHIFT;
-       return *(float64*)&x;
-}
-
-static float64
-modf(float64 d, float64 *ip)
-{
-       float64 dd;
-       uint64 x;
-       int32 e;
-
-       if(d < 1) {
-               if(d < 0) {
-                       d = modf(-d, ip);
-                       *ip = -*ip;
-                       return -d;
-               }
-               *ip = 0;
-               return d;
-       }
-
-       x = *(uint64*)&d;
-       e = (int32)((x >> SHIFT) & MASK) - BIAS;
-
-       /*
-        * Keep the top 11+e bits; clear the rest.
-        */
-       if(e <= 64-11)
-               x &= ~((uint64)1 << (64-11-e))-1;
-       dd = *(float64*)&x;
-       *ip = dd;
-       return d - dd;
-}
-
-// func frexp(float64) (int32, float64); // break fp into exp,fract
-void
-sys·frexp(float64 din, int32 iou, float64 dou)
-{
-       dou = frexp(din, &iou);
-       FLUSH(&dou);
-}
-
-//func ldexp(int32, float64) float64;  // make fp from exp,fract
-void
-sys·ldexp(float64 din, int32 ein, float64 dou)
-{
-       dou = ldexp(din, ein);
-       FLUSH(&dou);
-}
-
-//func modf(float64) (float64, float64);       // break fp into double+double
-float64
-sys·modf(float64 din, float64 dou1, float64 dou2)
-{
-       dou1 = modf(din, &dou2);
-       FLUSH(&dou2);
-}
-
-static int32   argc;
-static uint8** argv;
-static int32   envc;
-static uint8** envv;
-
-
-void
-args(int32 c, uint8 **v)
-{
-       argc = c;
-       argv = v;
-       envv = v + argc + 1;  // skip 0 at end of argv
-       for (envc = 0; envv[envc] != 0; envc++)
-               ;
-}
-
-//func argc() int32;  // return number of arguments
-void
-sys·argc(int32 v)
-{
-       v = argc;
-       FLUSH(&v);
-}
-
-//func envc() int32;  // return number of environment variables
-void
-sys·envc(int32 v)
-{
-       v = envc;
-       FLUSH(&v);
-}
-
-//func argv(i) string;  // return argument i
-void
-sys·argv(int32 i, string s)
-{
-       uint8* str;
-       int32 l;
-
-       if(i < 0 || i >= argc) {
-               s = emptystring;
-               goto out;
-       }
-
-       str = argv[i];
-       l = findnull((int8*)str);
-       s = mal(sizeof(s->len)+l);
-       s->len = l;
-       mcpy(s->str, str, l);
-
-out:
-       FLUSH(&s);
-}
-
-//func envv(i) string;  // return argument i
-void
-sys·envv(int32 i, string s)
-{
-       uint8* str;
-       int32 l;
-
-       if(i < 0 || i >= envc) {
-               s = emptystring;
-               goto out;
-       }
-
-       str = envv[i];
-       l = findnull((int8*)str);
-       s = mal(sizeof(s->len)+l);
-       s->len = l;
-       mcpy(s->str, str, l);
-
-out:
-       FLUSH(&s);
-}
-
-check(void)
-{
-       int8 a;
-       uint8 b;
-       int16 c;
-       uint16 d;
-       int32 e;
-       uint32 f;
-       int64 g;
-       uint64 h;
-       float32 i;
-       float64 j;
-       void* k;
-       uint16* l;
-
-       if(sizeof(a) != 1) throw("bad a");
-       if(sizeof(b) != 1) throw("bad b");
-       if(sizeof(c) != 2) throw("bad c");
-       if(sizeof(d) != 2) throw("bad d");
-       if(sizeof(e) != 4) throw("bad e");
-       if(sizeof(f) != 4) throw("bad f");
-       if(sizeof(g) != 8) throw("bad g");
-       if(sizeof(h) != 8) throw("bad h");
-       if(sizeof(i) != 4) throw("bad i");
-       if(sizeof(j) != 8) throw("bad j");
-       if(sizeof(k) != 8) throw("bad k");
-       if(sizeof(l) != 8) throw("bad l");
-//     prints(1"check ok\n");
-       initsig();
-}
-
-typedef        struct  Link    Link;
-typedef        struct  Hmap    Hmap;
-typedef        struct  Alg     Alg;
-
-struct Alg
-{
-       uint64  (*hash)(uint32, void*);
-       uint32  (*equal)(uint32, void*, void*);
-       void    (*print)(uint32, void*);
-       void    (*copy)(uint32, void*, void*);
-};
-
-struct Link
-{
-       Link*   link;
-       byte    data[8];
-};
-
-struct Hmap
-{
-       uint32  len;            // must be first
-       uint32  keysize;
-       uint32  valsize;
-       uint32  hint;
-       Alg*    keyalg;
-       Alg*    valalg;
-       uint32  valoffset;
-       uint32  ko;
-       uint32  vo;
-       uint32  po;
-       Link*   link;
-};
-
-static uint64
-memhash(uint32 s, void *a)
-{
-       prints("memhash\n");
-       return 0x12345;
-}
-
-static uint32
-memequal(uint32 s, void *a, void *b)
-{
-       byte *ba, *bb;
-       uint32 i;
-
-       ba = a;
-       bb = b;
-       for(i=0; i<s; i++)
-               if(ba[i] != bb[i])
-                       return 0;
-       return 1;
-}
-
-static void
-memprint(uint32 s, void *a)
-{
-       uint64 v;
-
-       v = 0xbadb00b;
-       switch(s) {
-       case 1:
-               v = *(uint8*)a;
-               break;
-       case 2:
-               v = *(uint16*)a;
-               break;
-       case 4:
-               v = *(uint32*)a;
-               break;
-       case 8:
-               v = *(uint64*)a;
-               break;
-       }
-       sys·printint(v);
-}
-
-static void
-memcopy(uint32 s, void *a, void *b)
-{
-       byte *ba, *bb;
-       uint32 i;
-
-       ba = a;
-       bb = b;
-       if(bb == nil) {
-               for(i=0; i<s; i++)
-                       ba[i] = 0;
-               return;
-       }
-       for(i=0; i<s; i++)
-               ba[i] = bb[i];
-}
-
-static uint64
-stringhash(uint32 s, string *a)
-{
-       prints("stringhash\n");
-       return 0x12345;
-}
-
-static uint32
-stringequal(uint32 s, string *a, string *b)
-{
-       return cmpstring(*a, *b) == 0;
-}
-
-static void
-stringprint(uint32 s, string *a)
-{
-       sys·printstring(*a);
-}
-
-static void
-stringcopy(uint32 s, string *a, string *b)
-{
-       if(b == nil) {
-               *a = nil;
-               return;
-       }
-       *a = *b;
-}
-
-static uint64
-pointerhash(uint32 s, void **a)
-{
-       prints("pointerhash\n");
-       return 0x12345;
-}
-
-static uint32
-pointerequal(uint32 s, void **a, void **b)
-{
-       prints("pointerequal\n");
-       return 0;
-}
-
-static void
-pointerprint(uint32 s, void **a)
-{
-       prints("pointerprint\n");
-}
-
-static void
-pointercopy(uint32 s, void **a, void **b)
-{
-       if(b == nil) {
-               *a = nil;
-               return;
-       }
-       *a = *b;
-}
-
-static uint32
-rnd(uint32 n, uint32 m)
-{
-       uint32 r;
-
-       r = n % m;
-       if(r)
-               n += m-r;
-       return n;
-}
-
-static Alg
-algarray[] =
-{
-       {       &memhash,       &memequal,      &memprint,      &memcopy        },
-       {       &stringhash,    &stringequal,   &stringprint,   &stringcopy     },
-       {       &pointerhash,   &pointerequal,  &pointerprint,  &pointercopy    },
-};
-
-// newmap(keysize uint32, valsize uint32,
-//     keyalg uint32, valalg uint32,
-//     hint uint32) (hmap *map[any]any);
-void
-sys·newmap(uint32 keysize, uint32 valsize,
-       uint32 keyalg, uint32 valalg, uint32 hint,
-       Hmap* ret)
-{
-       Hmap *m;
-
-       if(keyalg >= 2 ||
-          valalg >= 3) {
-               prints("0<=");
-               sys·printint(keyalg);
-               prints("<");
-               sys·printint(nelem(algarray));
-               prints("\n0<=");
-               sys·printint(valalg);
-               prints("<");
-               sys·printint(nelem(algarray));
-               prints("\n");
-
-               throw("sys·newmap: key/val algorithm out of range");
-       }
-
-       m = mal(sizeof(*m));
-
-       m->len = 0;
-       m->keysize = keysize;
-       m->valsize = valsize;
-       m->keyalg = &algarray[keyalg];
-       m->valalg = &algarray[valalg];
-       m->hint = hint;
-
-       // these calculations are compiler dependent
-       m->valoffset = rnd(keysize, valsize);
-       m->ko = rnd(sizeof(m), keysize);
-       m->vo = rnd(m->ko+keysize, valsize);
-       m->po = rnd(m->vo+valsize, 1);
-
-       ret = m;
-       FLUSH(&ret);
-
-       if(debug) {
-               prints("newmap: map=");
-               sys·printpointer(m);
-               prints("; keysize=");
-               sys·printint(keysize);
-               prints("; valsize=");
-               sys·printint(valsize);
-               prints("; keyalg=");
-               sys·printint(keyalg);
-               prints("; valalg=");
-               sys·printint(valalg);
-               prints("; valoffset=");
-               sys·printint(m->valoffset);
-               prints("; ko=");
-               sys·printint(m->ko);
-               prints("; vo=");
-               sys·printint(m->vo);
-               prints("; po=");
-               sys·printint(m->po);
-               prints("\n");
-       }
-}
-
-// mapaccess1(hmap *map[any]any, key any) (val any);
-void
-sys·mapaccess1(Hmap *m, ...)
-{
-       Link *l;
-       byte *ak, *av;
-
-       ak = (byte*)&m + m->ko;
-       av = (byte*)&m + m->vo;
-
-       for(l=m->link; l!=nil; l=l->link) {
-               if(m->keyalg->equal(m->keysize, ak, l->data)) {
-                       m->valalg->copy(m->valsize, av, l->data+m->valoffset);
-                       goto out;
-               }
-       }
-
-       m->valalg->copy(m->valsize, av, 0);
-
-out:
-       if(debug) {
-               prints("sys·mapaccess1: map=");
-               sys·printpointer(m);
-               prints("; key=");
-               m->keyalg->print(m->keysize, ak);
-               prints("; val=");
-               m->valalg->print(m->valsize, av);
-               prints("\n");
-       }
-}
-
-// mapaccess2(hmap *map[any]any, key any) (val any, pres bool);
-void
-sys·mapaccess2(Hmap *m, ...)
-{
-       Link *l;
-       byte *ak, *av, *ap;
-
-       ak = (byte*)&m + m->ko;
-       av = (byte*)&m + m->vo;
-       ap = (byte*)&m + m->po;
-
-       for(l=m->link; l!=nil; l=l->link) {
-               if(m->keyalg->equal(m->keysize, ak, l->data)) {
-                       *ap = true;
-                       m->valalg->copy(m->valsize, av, l->data+m->valoffset);
-                       goto out;
-               }
-       }
-
-       *ap = false;
-       m->valalg->copy(m->valsize, av, nil);
-
-out:
-       if(debug) {
-               prints("sys·mapaccess2: map=");
-               sys·printpointer(m);
-               prints("; key=");
-               m->keyalg->print(m->keysize, ak);
-               prints("; val=");
-               m->valalg->print(m->valsize, av);
-               prints("; pres=");
-               sys·printbool(*ap);
-               prints("\n");
-       }
-}
-
-static void
-sys·mapassign(Hmap *m, byte *ak, byte *av)
-{
-       Link *l;
-
-       // mapassign(hmap *map[any]any, key any, val any);
-
-       for(l=m->link; l!=nil; l=l->link) {
-               if(m->keyalg->equal(m->keysize, ak, l->data))
-                       goto out;
-       }
-
-       l = mal((sizeof(*l)-8) + m->keysize + m->valsize);
-       l->link = m->link;
-       m->link = l;
-       m->keyalg->copy(m->keysize, l->data, ak);
-       m->len++;
-
-out:
-       m->valalg->copy(m->valsize, l->data+m->valoffset, av);
-
-       if(debug) {
-               prints("mapassign: map=");
-               sys·printpointer(m);
-               prints("; key=");
-               m->keyalg->print(m->keysize, ak);
-               prints("; val=");
-               m->valalg->print(m->valsize, av);
-               prints("\n");
-       }
-}
-
-// mapassign1(hmap *map[any]any, key any, val any);
-void
-sys·mapassign1(Hmap *m, ...)
-{
-       Link **ll;
-       byte *ak, *av;
-
-       ak = (byte*)&m + m->ko;
-       av = (byte*)&m + m->vo;
-
-       sys·mapassign(m, ak, av);
-}
-
-// mapassign2(hmap *map[any]any, key any, val any, pres bool);
-void
-sys·mapassign2(Hmap *m, ...)
-{
-       Link **ll;
-       byte *ak, *av, *ap;
-
-       ak = (byte*)&m + m->ko;
-       av = (byte*)&m + m->vo;
-       ap = (byte*)&m + m->po;
-
-       if(*ap == true) {
-               // assign
-               sys·mapassign(m, ak, av);
-               return;
-       }
-
-       // delete
-       for(ll=&m->link; (*ll)!=nil; ll=&(*ll)->link) {
-               if(m->keyalg->equal(m->keysize, ak, (*ll)->data)) {
-                       m->valalg->copy(m->valsize, (*ll)->data+m->valoffset, nil);
-                       (*ll) = (*ll)->link;
-                       m->len--;
-                       if(debug) {
-                               prints("mapdelete (found): map=");
-                               sys·printpointer(m);
-                               prints("; key=");
-                               m->keyalg->print(m->keysize, ak);
-                               prints("\n");
-                       }
-                       return;
-               }
-       }
-
-       if(debug) {
-               prints("mapdelete (not found): map=");
-               sys·printpointer(m);
-               prints("; key=");
-               m->keyalg->print(m->keysize, ak);
-               prints(" *** not found\n");
-       }
-}
index c645992d8fb9e5262fd7574d996d6f35f47b1a99..bc183815f4e1c0fd40f8da03f2f6a5a23e31e72b 100644 (file)
@@ -79,6 +79,16 @@ enum
 #define        nelem(x)        (sizeof(x)/sizeof((x)[0]))
 #define        nil             ((void*)0)
 
+/*
+ * common functions and data
+ */
+int32 strcmp(byte*, byte*);
+int32 findnull(int8*);
+void   dump(byte*, int32);
+
+extern string  emptystring;
+extern int32 debug;
+
 /*
  * very low level c-called
  */
@@ -119,6 +129,7 @@ void        sys·printbool(bool);
 void   sys·printfloat(float64);
 void   sys·printint(int64);
 void   sys·printstring(string);
+void   sys·printpc(void*);
 void   sys·printpointer(void*);
 void   sys·catstring(string, string, string);
 void   sys·cmpstring(string, string, int32);
diff --git a/src/runtime/runtime_map.c b/src/runtime/runtime_map.c
new file mode 100644 (file)
index 0000000..ba9ff37
--- /dev/null
@@ -0,0 +1,827 @@
+// 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"
+
+static Map*    hash[1009];
+
+static Map*
+hashmap(Sigi *si, Sigs *ss)
+{
+       int32 ns, ni;
+       uint32 ihash, h;
+       byte *sname, *iname;
+       Map *m;
+
+       h = ((uint32)si + (uint32)ss) % nelem(hash);
+       for(m=hash[h]; m!=nil; m=m->link) {
+               if(m->si == si && m->ss == ss) {
+                       if(m->bad) {
+                               throw("bad hashmap");
+                               m = nil;
+                       }
+                       // prints("old hashmap\n");
+                       return m;
+               }
+       }
+
+       ni = si[0].offset;      // first word has size
+       m = mal(sizeof(*m) + ni*sizeof(m->fun[0]));
+       m->si = si;
+       m->ss = ss;
+
+       ni = 1;                 // skip first word
+       ns = 0;
+
+loop1:
+       // pick up next name from
+       // interface signature
+       iname = si[ni].name;
+       if(iname == nil) {
+               m->link = hash[h];
+               hash[h] = m;
+               // prints("new hashmap\n");
+               return m;
+       }
+       ihash = si[ni].hash;
+
+loop2:
+       // pick up and comapre next name
+       // from structure signature
+       sname = ss[ns].name;
+       if(sname == nil) {
+               prints((int8*)iname);
+               prints(": ");
+               throw("hashmap: failed to find method");
+               m->bad = 1;
+               m->link = hash[h];
+               hash[h] = m;
+               return nil;
+       }
+       if(ihash != ss[ns].hash ||
+          strcmp(sname, iname) != 0) {
+               ns++;
+               goto loop2;
+       }
+
+       m->fun[si[ni].offset] = ss[ns].fun;
+       ni++;
+       goto loop1;
+}
+
+void
+sys·ifaces2i(Sigi *si, Sigs *ss, Map *m, void *s)
+{
+
+       if(debug) {
+               prints("s2i sigi=");
+               sys·printpointer(si);
+               prints(" sigs=");
+               sys·printpointer(ss);
+               prints(" s=");
+               sys·printpointer(s);
+       }
+
+       if(s == nil) {
+               throw("ifaces2i: nil pointer");
+               m = nil;
+               FLUSH(&m);
+               return;
+       }
+
+       m = hashmap(si, ss);
+
+       if(debug) {
+               prints(" returning m=");
+               sys·printpointer(m);
+               prints(" s=");
+               sys·printpointer(s);
+               prints("\n");
+               dump((byte*)m, 64);
+       }
+
+       FLUSH(&m);
+}
+
+void
+sys·ifacei2i(Sigi *si, Map *m, void *s)
+{
+
+       if(debug) {
+               prints("i2i sigi=");
+               sys·printpointer(si);
+               prints(" m=");
+               sys·printpointer(m);
+               prints(" s=");
+               sys·printpointer(s);
+       }
+
+       if(m == nil) {
+               throw("ifacei2i: nil map");
+               s = nil;
+               FLUSH(&s);
+               return;
+       }
+
+       if(m->si == nil) {
+               throw("ifacei2i: nil pointer");
+               return;
+       }
+
+       if(m->si != si) {
+               m = hashmap(si, m->ss);
+               FLUSH(&m);
+       }
+
+       if(debug) {
+               prints(" returning m=");
+               sys·printpointer(m);
+               prints(" s=");
+               sys·printpointer(s);
+               prints("\n");
+               dump((byte*)m, 64);
+       }
+}
+
+void
+sys·ifacei2s(Sigs *ss, Map *m, void *s)
+{
+
+       if(debug) {
+               prints("i2s m=");
+               sys·printpointer(m);
+               prints(" s=");
+               sys·printpointer(s);
+               prints("\n");
+       }
+
+       if(m == nil) {
+               throw("ifacei2s: nil map");
+               s = nil;
+               FLUSH(&s);
+               return;
+       }
+
+       if(m->ss != ss) {
+               dump((byte*)m, 64);
+               throw("ifacei2s: wrong pointer");
+               s = nil;
+               FLUSH(&s);
+               return;
+       }
+}
+
+enum
+{
+       NANEXP          = 2047<<20,
+       NANMASK         = 2047<<20,
+       NANSIGN         = 1<<31,
+};
+
+static uint64  uvnan           = 0x7FF0000000000001;
+static uint64  uvinf           = 0x7FF0000000000000;
+static uint64  uvneginf        = 0xFFF0000000000000;
+
+static int32
+isInf(float64 d, int32 sign)
+{
+       uint64 x;
+
+       x = *(uint64*)&d;
+       if(sign == 0) {
+               if(x == uvinf || x == uvneginf)
+                       return 1;
+               return 0;
+       }
+       if(sign > 0) {
+               if(x == uvinf)
+                       return 1;
+               return 0;
+       }
+       if(x == uvneginf)
+               return 1;
+       return 0;
+}
+
+static float64
+NaN(void)
+{
+       return *(float64*)&uvnan;
+}
+
+static int32
+isNaN(float64 d)
+{
+       uint64 x;
+
+       x = *(uint64*)&d;
+       return ((uint32)x>>32)==0x7FF00000 && !isInf(d, 0);
+}
+
+static float64
+Inf(int32 sign)
+{
+       if(sign < 0)
+               return *(float64*)&uvinf;
+       else
+               return *(float64*)&uvneginf;
+}
+
+enum
+{
+       MASK    = 0x7ffL,
+       SHIFT   = 64-11-1,
+       BIAS    = 1022L,
+};
+
+static float64
+frexp(float64 d, int32 *ep)
+{
+       uint64 x;
+
+       if(d == 0) {
+               *ep = 0;
+               return 0;
+       }
+       x = *(uint64*)&d;
+       *ep = (int32)((x >> SHIFT) & MASK) - BIAS;
+       x &= ~((uint64)MASK << SHIFT);
+       x |= (uint64)BIAS << SHIFT;
+       return *(float64*)&x;
+}
+
+static float64
+ldexp(float64 d, int32 e)
+{
+       uint64 x;
+
+       if(d == 0)
+               return 0;
+       x = *(uint64*)&d;
+       e += (int32)(x >> SHIFT) & MASK;
+       if(e <= 0)
+               return 0;       /* underflow */
+       if(e >= MASK){          /* overflow */
+               if(d < 0)
+                       return Inf(-1);
+               return Inf(1);
+       }
+       x &= ~((uint64)MASK << SHIFT);
+       x |= (uint64)e << SHIFT;
+       return *(float64*)&x;
+}
+
+static float64
+modf(float64 d, float64 *ip)
+{
+       float64 dd;
+       uint64 x;
+       int32 e;
+
+       if(d < 1) {
+               if(d < 0) {
+                       d = modf(-d, ip);
+                       *ip = -*ip;
+                       return -d;
+               }
+               *ip = 0;
+               return d;
+       }
+
+       x = *(uint64*)&d;
+       e = (int32)((x >> SHIFT) & MASK) - BIAS;
+
+       /*
+        * Keep the top 11+e bits; clear the rest.
+        */
+       if(e <= 64-11)
+               x &= ~((uint64)1 << (64-11-e))-1;
+       dd = *(float64*)&x;
+       *ip = dd;
+       return d - dd;
+}
+
+// func frexp(float64) (int32, float64); // break fp into exp,fract
+void
+sys·frexp(float64 din, int32 iou, float64 dou)
+{
+       dou = frexp(din, &iou);
+       FLUSH(&dou);
+}
+
+//func ldexp(int32, float64) float64;  // make fp from exp,fract
+void
+sys·ldexp(float64 din, int32 ein, float64 dou)
+{
+       dou = ldexp(din, ein);
+       FLUSH(&dou);
+}
+
+//func modf(float64) (float64, float64);       // break fp into double+double
+float64
+sys·modf(float64 din, float64 dou1, float64 dou2)
+{
+       dou1 = modf(din, &dou2);
+       FLUSH(&dou2);
+}
+
+static int32   argc;
+static uint8** argv;
+static int32   envc;
+static uint8** envv;
+
+
+void
+args(int32 c, uint8 **v)
+{
+       argc = c;
+       argv = v;
+       envv = v + argc + 1;  // skip 0 at end of argv
+       for (envc = 0; envv[envc] != 0; envc++)
+               ;
+}
+
+//func argc() int32;  // return number of arguments
+void
+sys·argc(int32 v)
+{
+       v = argc;
+       FLUSH(&v);
+}
+
+//func envc() int32;  // return number of environment variables
+void
+sys·envc(int32 v)
+{
+       v = envc;
+       FLUSH(&v);
+}
+
+//func argv(i) string;  // return argument i
+void
+sys·argv(int32 i, string s)
+{
+       uint8* str;
+       int32 l;
+
+       if(i < 0 || i >= argc) {
+               s = emptystring;
+               goto out;
+       }
+
+       str = argv[i];
+       l = findnull((int8*)str);
+       s = mal(sizeof(s->len)+l);
+       s->len = l;
+       mcpy(s->str, str, l);
+
+out:
+       FLUSH(&s);
+}
+
+//func envv(i) string;  // return argument i
+void
+sys·envv(int32 i, string s)
+{
+       uint8* str;
+       int32 l;
+
+       if(i < 0 || i >= envc) {
+               s = emptystring;
+               goto out;
+       }
+
+       str = envv[i];
+       l = findnull((int8*)str);
+       s = mal(sizeof(s->len)+l);
+       s->len = l;
+       mcpy(s->str, str, l);
+
+out:
+       FLUSH(&s);
+}
+
+check(void)
+{
+       int8 a;
+       uint8 b;
+       int16 c;
+       uint16 d;
+       int32 e;
+       uint32 f;
+       int64 g;
+       uint64 h;
+       float32 i;
+       float64 j;
+       void* k;
+       uint16* l;
+
+       if(sizeof(a) != 1) throw("bad a");
+       if(sizeof(b) != 1) throw("bad b");
+       if(sizeof(c) != 2) throw("bad c");
+       if(sizeof(d) != 2) throw("bad d");
+       if(sizeof(e) != 4) throw("bad e");
+       if(sizeof(f) != 4) throw("bad f");
+       if(sizeof(g) != 8) throw("bad g");
+       if(sizeof(h) != 8) throw("bad h");
+       if(sizeof(i) != 4) throw("bad i");
+       if(sizeof(j) != 8) throw("bad j");
+       if(sizeof(k) != 8) throw("bad k");
+       if(sizeof(l) != 8) throw("bad l");
+//     prints(1"check ok\n");
+       initsig();
+}
+
+typedef        struct  Link    Link;
+typedef        struct  Hmap    Hmap;
+typedef        struct  Alg     Alg;
+
+struct Alg
+{
+       uint64  (*hash)(uint32, void*);
+       uint32  (*equal)(uint32, void*, void*);
+       void    (*print)(uint32, void*);
+       void    (*copy)(uint32, void*, void*);
+};
+
+struct Link
+{
+       Link*   link;
+       byte    data[8];
+};
+
+struct Hmap
+{
+       uint32  len;            // must be first
+       uint32  keysize;
+       uint32  valsize;
+       uint32  hint;
+       Alg*    keyalg;
+       Alg*    valalg;
+       uint32  valoffset;
+       uint32  ko;
+       uint32  vo;
+       uint32  po;
+       Link*   link;
+};
+
+static uint64
+memhash(uint32 s, void *a)
+{
+       prints("memhash\n");
+       return 0x12345;
+}
+
+static uint32
+memequal(uint32 s, void *a, void *b)
+{
+       byte *ba, *bb;
+       uint32 i;
+
+       ba = a;
+       bb = b;
+       for(i=0; i<s; i++)
+               if(ba[i] != bb[i])
+                       return 0;
+       return 1;
+}
+
+static void
+memprint(uint32 s, void *a)
+{
+       uint64 v;
+
+       v = 0xbadb00b;
+       switch(s) {
+       case 1:
+               v = *(uint8*)a;
+               break;
+       case 2:
+               v = *(uint16*)a;
+               break;
+       case 4:
+               v = *(uint32*)a;
+               break;
+       case 8:
+               v = *(uint64*)a;
+               break;
+       }
+       sys·printint(v);
+}
+
+static void
+memcopy(uint32 s, void *a, void *b)
+{
+       byte *ba, *bb;
+       uint32 i;
+
+       ba = a;
+       bb = b;
+       if(bb == nil) {
+               for(i=0; i<s; i++)
+                       ba[i] = 0;
+               return;
+       }
+       for(i=0; i<s; i++)
+               ba[i] = bb[i];
+}
+
+static uint64
+stringhash(uint32 s, string *a)
+{
+       prints("stringhash\n");
+       return 0x12345;
+}
+
+static uint32
+stringequal(uint32 s, string *a, string *b)
+{
+       return cmpstring(*a, *b) == 0;
+}
+
+static void
+stringprint(uint32 s, string *a)
+{
+       sys·printstring(*a);
+}
+
+static void
+stringcopy(uint32 s, string *a, string *b)
+{
+       if(b == nil) {
+               *a = nil;
+               return;
+       }
+       *a = *b;
+}
+
+static uint64
+pointerhash(uint32 s, void **a)
+{
+       prints("pointerhash\n");
+       return 0x12345;
+}
+
+static uint32
+pointerequal(uint32 s, void **a, void **b)
+{
+       prints("pointerequal\n");
+       return 0;
+}
+
+static void
+pointerprint(uint32 s, void **a)
+{
+       prints("pointerprint\n");
+}
+
+static void
+pointercopy(uint32 s, void **a, void **b)
+{
+       if(b == nil) {
+               *a = nil;
+               return;
+       }
+       *a = *b;
+}
+
+static uint32
+rnd(uint32 n, uint32 m)
+{
+       uint32 r;
+
+       r = n % m;
+       if(r)
+               n += m-r;
+       return n;
+}
+
+static Alg
+algarray[] =
+{
+       {       &memhash,       &memequal,      &memprint,      &memcopy        },
+       {       &stringhash,    &stringequal,   &stringprint,   &stringcopy     },
+       {       &pointerhash,   &pointerequal,  &pointerprint,  &pointercopy    },
+};
+
+// newmap(keysize uint32, valsize uint32,
+//     keyalg uint32, valalg uint32,
+//     hint uint32) (hmap *map[any]any);
+void
+sys·newmap(uint32 keysize, uint32 valsize,
+       uint32 keyalg, uint32 valalg, uint32 hint,
+       Hmap* ret)
+{
+       Hmap *m;
+
+       if(keyalg >= 2 ||
+          valalg >= 3) {
+               prints("0<=");
+               sys·printint(keyalg);
+               prints("<");
+               sys·printint(nelem(algarray));
+               prints("\n0<=");
+               sys·printint(valalg);
+               prints("<");
+               sys·printint(nelem(algarray));
+               prints("\n");
+
+               throw("sys·newmap: key/val algorithm out of range");
+       }
+
+       m = mal(sizeof(*m));
+
+       m->len = 0;
+       m->keysize = keysize;
+       m->valsize = valsize;
+       m->keyalg = &algarray[keyalg];
+       m->valalg = &algarray[valalg];
+       m->hint = hint;
+
+       // these calculations are compiler dependent
+       m->valoffset = rnd(keysize, valsize);
+       m->ko = rnd(sizeof(m), keysize);
+       m->vo = rnd(m->ko+keysize, valsize);
+       m->po = rnd(m->vo+valsize, 1);
+
+       ret = m;
+       FLUSH(&ret);
+
+       if(debug) {
+               prints("newmap: map=");
+               sys·printpointer(m);
+               prints("; keysize=");
+               sys·printint(keysize);
+               prints("; valsize=");
+               sys·printint(valsize);
+               prints("; keyalg=");
+               sys·printint(keyalg);
+               prints("; valalg=");
+               sys·printint(valalg);
+               prints("; valoffset=");
+               sys·printint(m->valoffset);
+               prints("; ko=");
+               sys·printint(m->ko);
+               prints("; vo=");
+               sys·printint(m->vo);
+               prints("; po=");
+               sys·printint(m->po);
+               prints("\n");
+       }
+}
+
+// mapaccess1(hmap *map[any]any, key any) (val any);
+void
+sys·mapaccess1(Hmap *m, ...)
+{
+       Link *l;
+       byte *ak, *av;
+
+       ak = (byte*)&m + m->ko;
+       av = (byte*)&m + m->vo;
+
+       for(l=m->link; l!=nil; l=l->link) {
+               if(m->keyalg->equal(m->keysize, ak, l->data)) {
+                       m->valalg->copy(m->valsize, av, l->data+m->valoffset);
+                       goto out;
+               }
+       }
+
+       m->valalg->copy(m->valsize, av, 0);
+
+out:
+       if(debug) {
+               prints("sys·mapaccess1: map=");
+               sys·printpointer(m);
+               prints("; key=");
+               m->keyalg->print(m->keysize, ak);
+               prints("; val=");
+               m->valalg->print(m->valsize, av);
+               prints("\n");
+       }
+}
+
+// mapaccess2(hmap *map[any]any, key any) (val any, pres bool);
+void
+sys·mapaccess2(Hmap *m, ...)
+{
+       Link *l;
+       byte *ak, *av, *ap;
+
+       ak = (byte*)&m + m->ko;
+       av = (byte*)&m + m->vo;
+       ap = (byte*)&m + m->po;
+
+       for(l=m->link; l!=nil; l=l->link) {
+               if(m->keyalg->equal(m->keysize, ak, l->data)) {
+                       *ap = true;
+                       m->valalg->copy(m->valsize, av, l->data+m->valoffset);
+                       goto out;
+               }
+       }
+
+       *ap = false;
+       m->valalg->copy(m->valsize, av, nil);
+
+out:
+       if(debug) {
+               prints("sys·mapaccess2: map=");
+               sys·printpointer(m);
+               prints("; key=");
+               m->keyalg->print(m->keysize, ak);
+               prints("; val=");
+               m->valalg->print(m->valsize, av);
+               prints("; pres=");
+               sys·printbool(*ap);
+               prints("\n");
+       }
+}
+
+static void
+sys·mapassign(Hmap *m, byte *ak, byte *av)
+{
+       Link *l;
+
+       // mapassign(hmap *map[any]any, key any, val any);
+
+       for(l=m->link; l!=nil; l=l->link) {
+               if(m->keyalg->equal(m->keysize, ak, l->data))
+                       goto out;
+       }
+
+       l = mal((sizeof(*l)-8) + m->keysize + m->valsize);
+       l->link = m->link;
+       m->link = l;
+       m->keyalg->copy(m->keysize, l->data, ak);
+       m->len++;
+
+out:
+       m->valalg->copy(m->valsize, l->data+m->valoffset, av);
+
+       if(debug) {
+               prints("mapassign: map=");
+               sys·printpointer(m);
+               prints("; key=");
+               m->keyalg->print(m->keysize, ak);
+               prints("; val=");
+               m->valalg->print(m->valsize, av);
+               prints("\n");
+       }
+}
+
+// mapassign1(hmap *map[any]any, key any, val any);
+void
+sys·mapassign1(Hmap *m, ...)
+{
+       Link **ll;
+       byte *ak, *av;
+
+       ak = (byte*)&m + m->ko;
+       av = (byte*)&m + m->vo;
+
+       sys·mapassign(m, ak, av);
+}
+
+// mapassign2(hmap *map[any]any, key any, val any, pres bool);
+void
+sys·mapassign2(Hmap *m, ...)
+{
+       Link **ll;
+       byte *ak, *av, *ap;
+
+       ak = (byte*)&m + m->ko;
+       av = (byte*)&m + m->vo;
+       ap = (byte*)&m + m->po;
+
+       if(*ap == true) {
+               // assign
+               sys·mapassign(m, ak, av);
+               return;
+       }
+
+       // delete
+       for(ll=&m->link; (*ll)!=nil; ll=&(*ll)->link) {
+               if(m->keyalg->equal(m->keysize, ak, (*ll)->data)) {
+                       m->valalg->copy(m->valsize, (*ll)->data+m->valoffset, nil);
+                       (*ll) = (*ll)->link;
+                       m->len--;
+                       if(debug) {
+                               prints("mapdelete (found): map=");
+                               sys·printpointer(m);
+                               prints("; key=");
+                               m->keyalg->print(m->keysize, ak);
+                               prints("\n");
+                       }
+                       return;
+               }
+       }
+
+       if(debug) {
+               prints("mapdelete (not found): map=");
+               sys·printpointer(m);
+               prints("; key=");
+               m->keyalg->print(m->keysize, ak);
+               prints(" *** not found\n");
+       }
+}
diff --git a/src/runtime/runtime_print.c b/src/runtime/runtime_print.c
new file mode 100644 (file)
index 0000000..ebc461b
--- /dev/null
@@ -0,0 +1,108 @@
+// 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"
+
+
+void
+dump(byte *p, int32 n)
+{
+       uint32 v;
+       int32 i;
+
+       for(i=0; i<n; i++) {
+               sys·printpointer((byte*)(p[i]>>4));
+               sys·printpointer((byte*)(p[i]&0xf));
+               if((i&15) == 15)
+                       prints("\n");
+               else
+                       prints(" ");
+       }
+       if(n & 15)
+               prints("\n");
+}
+
+void
+prints(int8 *s)
+{
+       sys·write(1, s, findnull(s));
+}
+
+void
+sys·printpc(void *p)
+{
+       prints("PC=0x");
+       sys·printpointer(sys·getcallerpc(p));
+}
+
+void
+sys·printbool(bool v)
+{
+       if(v) {
+               sys·write(1, (byte*)"true", 4);
+               return;
+       }
+       sys·write(1, (byte*)"false", 5);
+}
+
+void
+sys·printfloat(float64 v)
+{
+       sys·write(1, "printfloat", 10);
+}
+
+void
+sys·printint(int64 v)
+{
+       byte buf[100];
+       int32 i, s;
+
+       s = 0;
+       if(v < 0) {
+               v = -v;
+               s = 1;
+               if(v < 0) {
+                       sys·write(1, (byte*)"-oo", 3);
+                       return;
+               }
+       }
+
+       for(i=nelem(buf)-1; i>0; i--) {
+               buf[i] = v%10 + '0';
+               if(v < 10)
+                       break;
+               v = v/10;
+       }
+       if(s) {
+               i--;
+               buf[i] = '-';
+       }
+       sys·write(1, buf+i, nelem(buf)-i);
+}
+
+void
+sys·printpointer(void *p)
+{
+       uint64 v;
+       byte buf[100];
+       int32 i;
+
+       v = (int64)p;
+       for(i=nelem(buf)-1; i>0; i--) {
+               buf[i] = v%16 + '0';
+               if(buf[i] > '9')
+                       buf[i] += 'a'-'0'-10;
+               if(v < 16)
+                       break;
+               v = v/16;
+       }
+       sys·write(1, buf+i, nelem(buf)-i);
+}
+
+void
+sys·printstring(string v)
+{
+       if(v != nil)
+               sys·write(1, v->str, v->len);
+}
diff --git a/src/runtime/runtime_string.c b/src/runtime/runtime_string.c
new file mode 100644 (file)
index 0000000..9bac091
--- /dev/null
@@ -0,0 +1,220 @@
+// 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"
+
+static int32   empty           = 0;
+string emptystring     = (string)&empty;
+
+int32
+findnull(int8 *s)
+{
+       int32 l;
+
+       for(l=0; s[l]!=0; l++)
+               ;
+       return l;
+}
+
+void
+sys·catstring(string s1, string s2, string s3)
+{
+       uint32 l;
+
+       if(s1 == nil || s1->len == 0) {
+               s3 = s2;
+               goto out;
+       }
+       if(s2 == nil || s2->len == 0) {
+               s3 = s1;
+               goto out;
+       }
+
+       l = s1->len + s2->len;
+
+       s3 = mal(sizeof(s3->len)+l);
+       s3->len = l;
+       mcpy(s3->str, s1->str, s1->len);
+       mcpy(s3->str+s1->len, s2->str, s2->len);
+
+out:
+       FLUSH(&s3);
+}
+
+static void
+prbounds(int8* s, int32 a, int32 b, int32 c)
+{
+       int32 i;
+
+       prints(s);
+       prints(" ");
+       sys·printint(a);
+       prints("<");
+       sys·printint(b);
+       prints(">");
+       sys·printint(c);
+       prints("\n");
+       throw("bounds");
+}
+
+uint32
+cmpstring(string s1, string s2)
+{
+       uint32 i, l;
+       byte c1, c2;
+
+       if(s1 == nil)
+               s1 = emptystring;
+       if(s2 == nil)
+               s2 = emptystring;
+
+       l = s1->len;
+       if(s2->len < l)
+               l = s2->len;
+       for(i=0; i<l; i++) {
+               c1 = s1->str[i];
+               c2 = s2->str[i];
+               if(c1 < c2)
+                       return -1;
+               if(c1 > c2)
+                       return +1;
+       }
+       if(s1->len < s2->len)
+               return -1;
+       if(s1->len > s2->len)
+               return +1;
+       return 0;
+}
+
+void
+sys·cmpstring(string s1, string s2, int32 v)
+{
+       v = cmpstring(s1, s2);
+       FLUSH(&v);
+}
+
+int32
+strcmp(byte *s1, byte *s2)
+{
+       uint32 i;
+       byte c1, c2;
+
+       for(i=0;; i++) {
+               c1 = s1[i];
+               c2 = s2[i];
+               if(c1 < c2)
+                       return -1;
+               if(c1 > c2)
+                       return +1;
+               if(c1 == 0)
+                       return 0;
+       }
+}
+
+void
+sys·slicestring(string si, int32 lindex, int32 hindex, string so)
+{
+       string s, str;
+       int32 l;
+
+       if(si == nil)
+               si = emptystring;
+
+       if(lindex < 0 || lindex > si->len ||
+          hindex < lindex || hindex > si->len) {
+               sys·printpc(&si);
+               prints(" ");
+               prbounds("slice", lindex, si->len, hindex);
+       }
+
+       l = hindex-lindex;
+       so = mal(sizeof(so->len)+l);
+       so->len = l;
+       mcpy(so->str, si->str+lindex, l);
+       FLUSH(&so);
+}
+
+void
+sys·indexstring(string s, int32 i, byte b)
+{
+       if(s == nil)
+               s = emptystring;
+
+       if(i < 0 || i >= s->len) {
+               sys·printpc(&s);
+               prints(" ");
+               prbounds("index", 0, i, s->len);
+       }
+
+       b = s->str[i];
+       FLUSH(&b);
+}
+
+/*
+ * this is the plan9 runetochar
+ * extended for 36 bits in 7 bytes
+ * note that it truncates to 32 bits
+ * through the argument passing.
+ */
+static int32
+runetochar(byte *str, uint32 c)
+{
+       int32 i, n;
+       uint32 mask, mark;
+
+       /*
+        * one character in 7 bits
+        */
+       if(c <= 0x07FUL) {
+               str[0] = c;
+               return 1;
+       }
+
+       /*
+        * every new character picks up 5 bits
+        * one less in the first byte and
+        * six more in an extension byte
+        */
+       mask = 0x7ffUL;
+       mark = 0xC0UL;
+       for(n=1;; n++) {
+               if(c <= mask)
+                       break;
+               mask = (mask<<5) | 0x1fUL;
+               mark = (mark>>1) | 0x80UL;
+       }
+
+       /*
+        * lay down the bytes backwards
+        * n is the number of extension bytes
+        * mask is the max codepoint
+        * mark is the zeroth byte indicator
+        */
+       for(i=n; i>0; i--) {
+               str[i] = 0x80UL | (c&0x3fUL);
+               c >>= 6;
+       }
+
+       str[0] = mark|c;
+       return n+1;
+}
+
+void
+sys·intstring(int64 v, string s)
+{
+       int32 l;
+
+       s = mal(sizeof(s->len)+8);
+       s->len = runetochar(s->str, v);
+       FLUSH(&s);
+}
+
+void
+sys·byteastring(byte *a, int32 l, string s)
+{
+       s = mal(sizeof(s->len)+l);
+       s->len = l;
+       mcpy(s->str, a, l);
+       FLUSH(&s);
+}
diff --git a/src/runtime/sys_amd64_darwin.s b/src/runtime/sys_amd64_darwin.s
new file mode 100644 (file)
index 0000000..16b999b
--- /dev/null
@@ -0,0 +1,110 @@
+// 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.
+
+//
+// System calls and other sys.stuff for AMD64, Darwin
+//
+
+TEXT   sys·exit(SB),1,$-8
+       MOVL    8(SP), DI               // arg 1 exit status
+       MOVL    $(0x2000000+1), AX      // syscall entry
+       SYSCALL
+       CALL    notok(SB)
+       RET
+
+TEXT   sys·write(SB),1,$-8
+       MOVL    8(SP), DI               // arg 1 fid
+       MOVQ    16(SP), SI              // arg 2 buf
+       MOVL    24(SP), DX              // arg 3 count
+       MOVL    $(0x2000000+4), AX      // syscall entry
+       SYSCALL
+       JCC     2(PC)
+       CALL    notok(SB)
+       RET
+
+TEXT   open(SB),1,$-8
+       MOVQ    8(SP), DI
+       MOVL    16(SP), SI
+       MOVQ    $0, R10
+       MOVL    $(0x2000000+5), AX      // syscall entry
+       SYSCALL
+       RET
+
+TEXT   close(SB),1,$-8
+       MOVL    8(SP), DI
+       MOVL    $(0x2000000+6), AX      // syscall entry
+       SYSCALL
+       RET
+
+TEXT   fstat(SB),1,$-8
+       MOVL    8(SP), DI
+       MOVQ    16(SP), SI
+       MOVL    $(0x2000000+339), AX    // syscall entry; really fstat64
+       SYSCALL
+       RET
+
+TEXT   read(SB),1,$-8
+       MOVL    8(SP), DI
+       MOVQ    16(SP), SI
+       MOVL    24(SP), DX
+       MOVL    $(0x2000000+3), AX      // syscall entry
+       SYSCALL
+       RET
+
+TEXT   sys·sigaction(SB),1,$-8
+       MOVL    8(SP), DI               // arg 1 sig
+       MOVQ    16(SP), SI              // arg 2 act
+       MOVQ    24(SP), DX              // arg 3 oact
+       MOVQ    24(SP), CX              // arg 3 oact
+       MOVQ    24(SP), R10             // arg 3 oact
+       MOVL    $(0x2000000+46), AX     // syscall entry
+       SYSCALL
+       JCC     2(PC)
+       CALL    notok(SB)
+       RET
+
+TEXT sigtramp(SB),1,$24
+       MOVL    DX,0(SP)
+       MOVQ    CX,8(SP)
+       MOVQ    R8,16(SP)
+       CALL    sighandler(SB)
+       RET
+
+TEXT   sys·breakpoint(SB),1,$-8
+       BYTE    $0xcc
+       RET
+
+TEXT   sys·mmap(SB),1,$-8
+       MOVQ    8(SP), DI               // arg 1 addr
+       MOVL    16(SP), SI              // arg 2 len
+       MOVL    20(SP), DX              // arg 3 prot
+       MOVL    24(SP), R10             // arg 4 flags
+       MOVL    28(SP), R8              // arg 5 fid
+       MOVL    32(SP), R9              // arg 6 offset
+       MOVL    $(0x2000000+197), AX    // syscall entry
+       SYSCALL
+       JCC     2(PC)
+       CALL    notok(SB)
+       RET
+
+TEXT   notok(SB),1,$-8
+       MOVL    $0xf1, BP
+       MOVQ    BP, (BP)
+       RET
+
+TEXT   sys·memclr(SB),1,$-8
+       MOVQ    8(SP), DI               // arg 1 addr
+       MOVL    16(SP), CX              // arg 2 count
+       ADDL    $7, CX
+       SHRL    $3, CX
+       MOVQ    $0, AX
+       CLD
+       REP
+       STOSQ
+       RET
+
+TEXT   sys·getcallerpc+0(SB),1,$0
+       MOVQ    x+0(FP),AX
+       MOVQ    -8(AX),AX
+       RET
diff --git a/src/runtime/sys_amd64_linux.s b/src/runtime/sys_amd64_linux.s
new file mode 100644 (file)
index 0000000..993193b
--- /dev/null
@@ -0,0 +1,114 @@
+// 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.
+
+//
+// System calls and other sys.stuff for AMD64, Linux
+//
+
+TEXT   sys·exit(SB),1,$-8
+       MOVL    8(SP), DI
+       MOVL    $60, AX
+       SYSCALL
+       RET
+
+TEXT   sys·write(SB),1,$-8
+       MOVL    8(SP), DI
+       MOVQ    16(SP), SI
+       MOVL    24(SP), DX
+       MOVL    $1, AX                  // syscall entry
+       SYSCALL
+       RET
+
+TEXT   open(SB),1,$-8
+       MOVQ    8(SP), DI
+       MOVL    16(SP), SI
+       MOVL    $2, AX                  // syscall entry
+       SYSCALL
+       RET
+
+TEXT   close(SB),1,$-8
+       MOVL    8(SP), DI
+       MOVL    $3, AX                  // syscall entry
+       SYSCALL
+       RET
+
+TEXT   fstat(SB),1,$-8
+       MOVL    8(SP), DI
+       MOVQ    16(SP), SI
+       MOVL    $5, AX                  // syscall entry
+       SYSCALL
+       RET
+
+TEXT   read(SB),1,$-8
+       MOVL    8(SP), DI
+       MOVQ    16(SP), SI
+       MOVL    24(SP), DX
+       MOVL    $0, AX                  // syscall entry
+       SYSCALL
+       RET
+
+TEXT   sys·rt_sigaction(SB),1,$-8
+       MOVL    8(SP), DI
+       MOVQ    16(SP), SI
+       MOVQ    24(SP), DX
+       MOVQ    32(SP), CX
+       MOVL    CX, R10
+       MOVL    $13, AX                 // syscall entry
+       SYSCALL
+       RET
+
+TEXT   sigtramp(SB),1,$24
+       MOVQ    DI,0(SP)
+       MOVQ    SI,8(SP)
+       MOVQ    DX,16(SP)
+       CALL    sighandler(SB)
+       RET
+
+TEXT   sys·breakpoint(SB),1,$-8
+       BYTE    $0xcc
+       RET
+
+TEXT   sys·mmap(SB),1,$-8
+       MOVQ    8(SP), DI
+       MOVL    16(SP), SI
+       MOVL    20(SP), DX
+       MOVL    24(SP), CX
+       MOVL    28(SP), R8
+       MOVL    32(SP), R9
+
+/* flags arg for ANON is 1000 but sb 20 */
+       MOVL    CX, AX
+       ANDL    $~0x1000, CX
+       ANDL    $0x1000, AX
+       SHRL    $7, AX
+       ORL     AX, CX
+
+       MOVL    CX, R10
+       MOVL    $9, AX                  // syscall entry
+       SYSCALL
+       CMPQ    AX, $0xfffffffffffff001
+       JLS     2(PC)
+       CALL    notok(SB)
+       RET
+
+TEXT   notok(SB),1,$-8
+       MOVL    $0xf1, BP
+       MOVQ    BP, (BP)
+       RET
+
+TEXT   sys·memclr(SB),1,$-8
+       MOVQ    8(SP), DI               // arg 1 addr
+       MOVL    16(SP), CX              // arg 2 count (cannot be zero)
+       ADDL    $7, CX
+       SHRL    $3, CX
+       MOVQ    $0, AX
+       CLD
+       REP
+       STOSQ
+       RET
+
+TEXT   sys·getcallerpc+0(SB),1,$0
+       MOVQ    x+0(FP),AX
+       MOVQ    -8(AX),AX
+       RET