// LoadInto loads a virtual machine with an input stream. func LoadInto(c *vm.VM, in io.Reader) error { var p mem.Page cur := uint32(0) for { header, buf, e := Read(in) if e == io.EOF { return nil } if e != nil { return e } for i, b := range buf { addr := header.addr + uint32(i) id := mem.PageID(addr) if id == 0 { return fmt.Errorf("attempt to map system page") } if cur == 0 || cur != id { cur = id if !c.CheckPage(addr) { p = mem.NewPage() c.MapPage(addr, p) } } p.Write(addr&mem.PageMask, b) } } return nil }
func TestHelloWorld(t *testing.T) { c := New() // c.Log = os.Stdout out := new(bytes.Buffer) str := "Hello, world.\n" c.Stdout = out dpage := mem.NewPage() copy(dpage.Bytes(), []byte(str+"\000")) ipage := mem.NewPage() c.MapPage(mem.PageStart(1), ipage) c.MapPage(mem.PageStart(2), dpage) a := &mem.Align{ipage} offset := uint32(0) w := func(i inst.Inst) uint32 { ret := offset a.WriteU32(offset, i.U32()) offset += 4 return ret } /* add $1, $0, $0 ; init counter loop: lbu $2, $1[0x2000] ; load byte beq $2, $0, end ; +5 wait: lbu $3, $0[0x9] ; is output ready? bne $3, $0, wait ; -2 sb $2, $0[0x9] ; output byte addi $1, $1, 1 ; increase counter j loop ; -7 end: sb $0, [0x8] */ Rinst := inst.Rinst Iinst := inst.Iinst Jinst := inst.Jinst w(Rinst(0, 0, 1, inst.FnAdd)) // 000 w(Iinst(inst.OpLbu, 1, 2, 0x2000)) // 004 w(Iinst(inst.OpBeq, 2, 0, 0x0005)) // 008 w(Iinst(inst.OpLbu, 0, 3, 0x0009)) // 00c w(Iinst(inst.OpBne, 3, 0, 0xfffe)) // 010 w(Iinst(inst.OpSb, 0, 2, 0x0009)) // 014 w(Iinst(inst.OpAddi, 1, 1, 0x0001)) // 018 w(Jinst(inst.OpJ, -7)) // 01c w(Iinst(inst.OpSb, 0, 0, 0x0008)) // 020 c.SetPC(mem.PageStart(1)) used := c.Run(1000) if used > 150 { t.Fail() } if !c.RIP() { t.Fail() } if out.String() != str { t.Fail() } }
func TestSingleInst(t *testing.T) { c := vm.NewCore() p := mem.NewPage() c.Map(0, p) s := func(i Inst) { c.WriteReg(1, 0x1) c.WriteReg(2, 0x20) c.WriteReg(3, 0x300) c.WriteReg(4, 0) c.WriteReg(5, 0x31) c.WriteReg(6, 0xfffffff0) Exec(c, i) } r := Rinst rs := RinstShamt c4 := func(i Inst, v uint32) { s(i) if c.ReadReg(4) != v { t.Fail() } if c.ReadReg(0) != 0 { t.Fail() } } c4(r(0, 0, 4, FnAdd), 0) c4(r(2, 3, 4, FnAdd), 0x320) c4(r(3, 2, 4, FnAdd), 0x320) c4(r(3, 3, 4, FnAdd), 0x600) c4(r(2, 6, 4, FnAdd), 0x10) c4(r(0, 0, 4, FnSub), 0) c4(r(2, 0, 4, FnSub), 0x20) c4(r(2, 3, 4, FnSub), 0xfffffd20) c4(r(3, 2, 4, FnSub), 0x300-0x20) c4(r(3, 3, 4, FnSub), 0) c4(r(2, 6, 4, FnSub), 0x30) c4(r(0, 0, 4, FnAnd), 0) c4(r(2, 2, 4, FnAnd), 0x20) c4(r(5, 2, 4, FnAnd), 0x20) c4(r(2, 3, 4, FnAnd), 0) c4(rs(0, 2, 4, 2, FnSll), 0x20<<2) c4(rs(0, 2, 4, 0, FnSll), 0x20) c4(rs(0, 2, 4, 2, FnSrl), 0x20>>2) c4(rs(0, 2, 4, 0, FnSrl), 0x20) c4(rs(0, 1, 4, 2, FnSrl), 0) c4(rs(0, 6, 4, 2, FnSrl), 0x3ffffffc) c4(rs(0, 6, 4, 2, FnSra), 0xfffffffc) c4(r(1, 2, 4, FnSllv), 0x40) c4(r(2, 2, 4, FnSllv), 0) c4(r(0, 2, 4, FnSllv), 0x20) c4(r(1, 2, 4, FnSrlv), 0x10) c4(r(0, 2, 4, FnSrlv), 0x20) c4(r(1, 6, 4, FnSrlv), 0x7ffffff8) c4(r(1, 6, 4, FnSrav), 0xfffffff8) c4(r(2, 3, 4, FnXor), 0x320) c4(r(5, 2, 4, FnXor), 0x11) c4(r(2, 3, 4, FnOr), 0x320) c4(r(5, 2, 4, FnOr), 0x31) c4(r(2, 3, 4, FnNor), 0xffffffff-0x320) c4(r(5, 2, 4, FnNor), 0xffffffff-0x31) c4(r(5, 2, 4, FnSlt), 0) c4(r(2, 5, 4, FnSlt), 1) c4(r(2, 3, 4, FnMul), 0x6000) }