def test_intcheck(self): a = MyPPCAssembler() a.lwz(r5, r4, pystructs.PyVarObject.ob_size) a.cmpwi(r5, 1) a.bne("not_one") a.lwz(r5, r4, pystructs.PyTupleObject.ob_item + 0*4) a.lwz(r5, r5, 4) a.load_word(r6, lookup("PyInt_Type")) a.cmpw(r5, r6) a.bne("not_int") a.li(r3, 1) a.b("exit") a.label("not_int") a.li(r3, 0) a.b("exit") a.label("not_one") a.li(r3, 2) a.label("exit") a.load_word(r5, lookup("PyInt_FromLong")) a.mtctr(r5) a.bctr() f = a.assemble() assert f() == 2 assert f("", "") == 2 assert f("") == 0 assert f(1) == 1
def main(): a = MyPPCAssembler() a.lwz(r5, r4, 12) a.lwz(r6, r4, 16) a.lwz(r7, r5, 8) a.lwz(r8, r6, 8) a.add(r3, r7, r8) a.load_word(r4, lookup("PyInt_FromLong")) a.mtctr(r4) a.bctr() f = a.assemble(True) print f(12,3) a = MyPPCAssembler() a.label("loop") a.mftbu(r3) a.mftbl(r4) a.mftbu(r5) a.cmpw(r5, r3) a.bne(-16) a.load_word(r5, lookup("PyLong_FromUnsignedLongLong")) a.mtctr(r5) a.bctr() tb = a.assemble(True) t0 = tb() print [tb() - t0 for i in range(10)]
def wrap(funcname, retcode, signature): argcount = len(signature) ourcode = MyPPCAssembler() ourcode.mflr(r0) ourcode.stmw(r31, r1, -4) ourcode.stw(r0, r1, 8) ourcode.stwu(r1, r1, -80) ourcode.lwz(r3, r4, 8) ourcode.cmpwi(r3, argcount) ourcode.bne("argserror") assert argcount < 9 if argcount > 0: load_arg(ourcode, 0, signature[0]) for i in range(2, argcount): load_arg(ourcode, i, signature[i]) if argcount > 1: load_arg(ourcode, 1, signature[1]) ourcode.load_word(r0, lookup(funcname)) ourcode.mtctr(r0) ourcode.bctrl() if retcode == 'i': s = lookup("PyInt_FromLong") ourcode.load_word(r0, s) ourcode.mtctr(r0) ourcode.bctrl() elif retcode == 'f': s = lookup("PyFloat_FromDouble") ourcode.load_word(r0, s) ourcode.mtctr(r0) ourcode.bctrl() ourcode.label("epilogue") ourcode.lwz(r0, r1, 88) ourcode.addi(r1, r1, 80) ourcode.mtlr(r0) ourcode.lmw(r31, r1, -4) ourcode.blr() err_set = lookup("PyErr_SetObject") exc = lookup("PyExc_TypeError") ourcode.label("argserror") ourcode.load_word(r5, err_set) ourcode.mtctr(r5) ourcode.load_from(r3, exc) ourcode.mr(r4, r3) ourcode.bctrl() ourcode.li(r3, 0) ourcode.b("epilogue") return ourcode.assemble()
def main(): a = MyPPCAssembler() a.lwz(r5, r4, 12) a.lwz(r6, r4, 16) a.lwz(r7, r5, 8) a.lwz(r8, r6, 8) a.add(r3, r7, r8) a.load_word(r4, lookup("PyInt_FromLong")) a.mtctr(r4) a.bctr() f = a.assemble(True) print f(12, 3) a = MyPPCAssembler() a.label("loop") a.mftbu(r3) a.mftbl(r4) a.mftbu(r5) a.cmpw(r5, r3) a.bne(-16) a.load_word(r5, lookup("PyLong_FromUnsignedLongLong")) a.mtctr(r5) a.bctr() tb = a.assemble(True) t0 = tb() print[tb() - t0 for i in range(10)]
def load_arg(code, argi, typecode): rD = r3+argi code.lwz(rD, r4, 12 + 4*argi) if typecode == 'i': code.load_word(r0, lookup("PyInt_Type")) code.lwz(r31, rD, 4) # XXX ick! code.cmpw(r0, r31) code.bne("argserror") code.lwz(rD, rD, 8) elif typecode == 'f': code.load_word(r0, lookup("PyFloat_Type")) code.lwz(r31, rD, 4) code.cmpw(r0, r31) code.bne("argserror") code.lfd(rD-2, rD, 8) elif typecode != "O": raise Exception, "erk"
def test_numberadd(self): a = MyPPCAssembler() a.lwz(r5, r4, pystructs.PyVarObject.ob_size) a.cmpwi(r5, 2) a.bne("err_out") a.lwz(r3, r4, 12) a.lwz(r4, r4, 16) a.load_word(r5, lookup("PyNumber_Add")) a.mtctr(r5) a.bctr() a.label("err_out") a.mflr(r0) a.stw(r0, r1, 8) a.stwu(r1, r1, -80) err_set = lookup("PyErr_SetObject") exc = lookup("PyExc_TypeError") a.load_word(r5, err_set) a.mtctr(r5) a.load_from(r3, exc) a.mr(r4, r3) a.bctrl() a.li(r3, 0) a.lwz(r0, r1, 88) a.addi(r1, r1, 80) a.mtlr(r0) a.blr() f = a.assemble() raises(TypeError, f) raises(TypeError, f, '', 1) raises(TypeError, f, 1) raises(TypeError, f, 1, 2, 3) assert f(1, 2) == 3 assert f('a', 'b') == 'ab'
def test_makestring(self): a = MyPPCAssembler() a.li(r3, 0) a.li(r4, 0) a.load_word(r5, lookup("PyString_FromStringAndSize")) a.mtctr(r5) a.bctr() f = a.assemble() assert f() == ''
def test_less_simple(self): a = MyPPCAssembler() s = lookup("PyNumber_Add") a.load_word(r5, s) a.mtctr(r5) a.bctr() f = make_func(a, "O", "OO") raises(TypeError, f) raises(TypeError, f, 1) assert f(1, 2) == 3 raises(TypeError, f, 1, 2, 3)
def test_tuplelength(self): a = MyPPCAssembler() a.lwz(3, 4, pystructs.PyVarObject.ob_size) a.load_word(5, lookup("PyInt_FromLong")) a.mtctr(5) a.bctr() f = a.assemble() assert f() == 0 assert f(1) == 1 assert f('') == 1
def test_tuplelength2(self): a = MyPPCAssembler() a.mflr(0) a.stw(0, 1, 8) a.stwu(1, 1, -80) a.mr(3, 4) a.load_word(5, lookup("PyTuple_Size")) a.mtctr(5) a.bctrl() a.load_word(5, lookup("PyInt_FromLong")) a.mtctr(5) a.bctrl() a.lwz(0, 1, 88) a.addi(1, 1, 80) a.mtlr(0) a.blr() f = a.assemble() assert f() == 0 assert f(1) == 1 assert f('') == 1 assert f('', 3) == 2
def test_raise(self): a = MyPPCAssembler() a.mflr(0) a.stw(0, 1, 8) a.stwu(1, 1, -80) err_set = lookup("PyErr_SetObject") exc = lookup("PyExc_ValueError") a.load_word(5, err_set) a.mtctr(5) a.load_from(3, exc) a.mr(4, 3) a.bctrl() a.li(3, 0) a.lwz(0, 1, 88) a.addi(1, 1, 80) a.mtlr(0) a.blr() raises(ValueError, a.assemble())
def test_signature2(self): a = MyPPCAssembler() a.add(r3, r3, r4) a.add(r3, r3, r5) a.add(r3, r3, r6) a.add(r3, r3, r7) s = lookup("PyInt_FromLong") a.load_word(r0, s) a.mtctr(r0) a.bctr() f = make_func(a, "O", "iiiii") raises(TypeError, f) raises(TypeError, f, 1) assert f(1, 2, 3, 4, 5) == 1 + 2 + 3 + 4 + 5 raises(TypeError, f, 1, 2, 3) raises(TypeError, f, 1, "2", 3, 4, 5)
def make_func(code, retcode, signature, localwords=0): """code shouldn't contain prologue/epilogue (or touch r31)""" stacksize = 80 + 4*localwords argcount = len(signature) ourcode = MyPPCAssembler() ourcode.mflr(r0) ourcode.stmw(r31, r1, -4) ourcode.stw(r0, r1, 8) ourcode.stwu(r1, r1, -stacksize) ourcode.lwz(r3, r4, 8) ourcode.cmpwi(r3, argcount) ourcode.bne("argserror") assert argcount < 9 if argcount > 0: load_arg(ourcode, 0, signature[0]) for i in range(2, argcount): load_arg(ourcode, i, signature[i]) if argcount > 1: load_arg(ourcode, 1, signature[1]) ourcode.bl(FAST_ENTRY_LABEL) if retcode == 'i': s = lookup("PyInt_FromLong") ourcode.load_word(r0, s) ourcode.mtctr(r0) ourcode.bctrl() elif retcode == 'f': s = lookup("PyFloat_FromDouble") ourcode.load_word(r0, s) ourcode.mtctr(r0) ourcode.bctrl() ourcode.label("epilogue") ourcode.lwz(r0, r1, stacksize + 8) ourcode.addi(r1, r1, stacksize) ourcode.mtlr(r0) ourcode.lmw(r31, r1, -4) ourcode.blr() err_set = lookup("PyErr_SetObject") exc = lookup("PyExc_TypeError") ourcode.label("argserror") ourcode.load_word(r5, err_set) ourcode.mtctr(r5) ourcode.load_from(r3, exc) ourcode.mr(r4, r3) ourcode.bctrl() ourcode.li(r3, 0) ourcode.b("epilogue") ourcode.label(FAST_ENTRY_LABEL) # err, should be an Assembler method: l = {} for k in code.labels: l[k] = code.labels[k] + 4*len(ourcode.insts) r = code.rlabels.copy() for k in code.rlabels: r[k + 4*len(ourcode.insts)] = code.rlabels[k] ourcode.insts.extend(code.insts) ourcode.labels.update(l) ourcode.rlabels.update(r) r = ourcode.assemble() r.FAST_ENTRY_LABEL = ourcode.labels[FAST_ENTRY_LABEL] return r