PageRenderTime 74ms CodeModel.GetById 46ms RepoModel.GetById 0ms app.codeStats 1ms

/rpython/jit/backend/arm/test/test_calling_convention.py

https://bitbucket.org/pypy/pypy/
Python | 139 lines | 125 code | 10 blank | 4 comment | 1 complexity | daea74fe91aa2b0871606df23165a89c MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import py
  2. from rpython.rtyper.annlowlevel import llhelper
  3. from rpython.jit.metainterp.history import JitCellToken
  4. from rpython.jit.backend.test.calling_convention_test import CallingConvTests, parse
  5. from rpython.rtyper.lltypesystem import lltype
  6. from rpython.jit.codewriter.effectinfo import EffectInfo
  7. from rpython.jit.backend.arm.codebuilder import InstrBuilder
  8. from rpython.jit.backend.arm import registers as r
  9. from rpython.jit.backend.arm.test.support import skip_unless_run_slow_tests
  10. from rpython.jit.backend.arm.test.test_runner import boxfloat, constfloat
  11. from rpython.jit.metainterp.resoperation import rop, InputArgInt, InputArgFloat
  12. from rpython.jit.metainterp.history import JitCellToken
  13. skip_unless_run_slow_tests()
  14. boxint = InputArgInt
  15. boxfloat = InputArgFloat.fromfloat
  16. class TestARMCallingConvention(CallingConvTests):
  17. # ../../test/calling_convention_test.py
  18. def make_function_returning_stack_pointer(self):
  19. mc = InstrBuilder()
  20. mc.MOV_rr(r.r0.value, r.sp.value)
  21. mc.MOV_rr(r.pc.value, r.lr.value)
  22. return mc.materialize(self.cpu, [])
  23. def get_alignment_requirements(self):
  24. return 8
  25. def test_call_argument_spilling(self):
  26. # bug when we have a value in r0, that is overwritten by an argument
  27. # and needed after the call, so that the register gets spilled after it
  28. # was overwritten with the argument to the call
  29. def func(a):
  30. return a + 16
  31. I = lltype.Signed
  32. FUNC = self.FuncType([I], I)
  33. FPTR = self.Ptr(FUNC)
  34. func_ptr = llhelper(FPTR, func)
  35. calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL)
  36. funcbox = self.get_funcbox(self.cpu, func_ptr)
  37. args = ', '.join(['i%d' % i for i in range(11)])
  38. ops = """
  39. [%s]
  40. i99 = call(ConstClass(func_ptr), 22, descr=calldescr)
  41. guard_true(i0) [%s, i99]
  42. finish()""" % (args, args)
  43. loop = parse(ops, namespace=locals())
  44. looptoken = JitCellToken()
  45. self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
  46. args = [x for x in range(11)]
  47. deadframe = self.cpu.execute_token(looptoken, *args)
  48. for x in range(11):
  49. assert self.cpu.get_int_value(deadframe, x) == x
  50. assert self.cpu.get_int_value(deadframe, 11) == 38
  51. def test_float_hf_call_mixed(self):
  52. if not self.cpu.supports_floats:
  53. py.test.skip("requires floats")
  54. cpu = self.cpu
  55. callargs = []
  56. def func(f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9):
  57. callargs.append(zip(range(12),
  58. [f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9]))
  59. return f0 + f1 + f2 + f3 + f4 + f5 + f6 + float(i0 + i1) + f7 + f8 + f9
  60. F = lltype.Float
  61. I = lltype.Signed
  62. FUNC = self.FuncType([F] * 7 + [I] + [F] + [I] + [F]* 2, F)
  63. FPTR = self.Ptr(FUNC)
  64. func_ptr = llhelper(FPTR, func)
  65. calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  66. EffectInfo.MOST_GENERAL)
  67. funcbox = self.get_funcbox(cpu, func_ptr)
  68. args = ([boxfloat(.1) for i in range(7)] +
  69. [boxint(1), boxfloat(.2), boxint(2), boxfloat(.3),
  70. boxfloat(.4)])
  71. res = self.execute_operation(rop.CALL_F,
  72. [funcbox] + args,
  73. 'float', descr=calldescr)
  74. for i,j in enumerate(callargs[0]):
  75. box = args[i]
  76. if box.type == 'f':
  77. assert (i, args[i].getfloat()) == j
  78. else:
  79. assert (i, args[i].getint()) == j
  80. assert abs(res.getfloat() - 4.6) < 0.0001
  81. def test_float_hf_call_float(self):
  82. if not self.cpu.supports_floats:
  83. py.test.skip("requires floats")
  84. cpu = self.cpu
  85. callargs = []
  86. def func(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9):
  87. callargs.append(zip(range(10),
  88. [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9]))
  89. return f0 + f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9
  90. F = lltype.Float
  91. FUNC = self.FuncType([F] * 10, F)
  92. FPTR = self.Ptr(FUNC)
  93. func_ptr = llhelper(FPTR, func)
  94. calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  95. EffectInfo.MOST_GENERAL)
  96. funcbox = self.get_funcbox(cpu, func_ptr)
  97. args = ([boxfloat(.1) for i in range(10)])
  98. res = self.execute_operation(rop.CALL_F,
  99. [funcbox] + args,
  100. 'float', descr=calldescr)
  101. for i,j in enumerate(callargs[0]):
  102. assert (i, 0.1) == j
  103. assert abs(res.getfloat() - 1) < 0.0001
  104. def test_float_hf_call_int(self):
  105. cpu = self.cpu
  106. callargs = []
  107. def func(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9):
  108. callargs.append(zip(range(10),
  109. [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9]))
  110. return f0 + f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9
  111. I = lltype.Signed
  112. FUNC = self.FuncType([I] * 10, I)
  113. FPTR = self.Ptr(FUNC)
  114. func_ptr = llhelper(FPTR, func)
  115. calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  116. EffectInfo.MOST_GENERAL)
  117. funcbox = self.get_funcbox(cpu, func_ptr)
  118. args = ([boxint(1) for i in range(10)])
  119. res = self.execute_operation(rop.CALL_I,
  120. [funcbox] + args,
  121. 'int', descr=calldescr)
  122. for i,j in enumerate(callargs[0]):
  123. assert (i, 1) == j
  124. assert res.getint() == 10