PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/pypy/pypy/
Python | 303 lines | 268 code | 35 blank | 0 comment | 24 complexity | ae77ecdcf9c47a57cdacde8fca808122 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from rpython.jit.backend.arm import conditions as c
  2. from rpython.jit.backend.arm import registers as r
  3. from rpython.jit.backend.arm.assembler import AssemblerARM
  4. from rpython.jit.backend.arm.locations import imm
  5. from rpython.jit.backend.arm.test.support import run_asm
  6. from rpython.jit.backend.detect_cpu import getcpuclass
  7. from rpython.jit.metainterp.resoperation import rop
  8. from rpython.jit.codewriter import longlong
  9. from rpython.rtyper.annlowlevel import llhelper
  10. from rpython.rtyper.lltypesystem import lltype, rffi
  11. from rpython.jit.metainterp.history import JitCellToken
  12. from rpython.jit.backend.model import CompiledLoopToken
  13. from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
  14. from rpython.rtyper.annlowlevel import llhelper
  15. from rpython.rlib.objectmodel import specialize
  16. from rpython.rlib.debug import ll_assert
  17. CPU = getcpuclass()
  18. class TestRunningAssembler(object):
  19. def setup_method(self, method):
  20. cpu = CPU(None, None)
  21. self.a = AssemblerARM(cpu)
  22. self.a.setup_once()
  23. token = JitCellToken()
  24. clt = CompiledLoopToken(cpu, 0)
  25. clt.allgcrefs = []
  26. token.compiled_loop_token = clt
  27. self.a.setup(token)
  28. def test_make_operation_list(self):
  29. i = rop.INT_ADD
  30. from rpython.jit.backend.arm import assembler
  31. assert assembler.asm_operations[i] \
  32. is AssemblerARM.emit_op_int_add.im_func
  33. def test_load_small_int_to_reg(self):
  34. self.a.gen_func_prolog()
  35. self.a.mc.gen_load_int(r.r0.value, 123)
  36. self.a.gen_func_epilog()
  37. assert run_asm(self.a) == 123
  38. def test_load_medium_int_to_reg(self):
  39. self.a.gen_func_prolog()
  40. self.a.mc.gen_load_int(r.r0.value, 0xBBD7)
  41. self.a.gen_func_epilog()
  42. assert run_asm(self.a) == 48087
  43. def test_load_int_to_reg(self):
  44. self.a.gen_func_prolog()
  45. self.a.mc.gen_load_int(r.r0.value, 0xFFFFFF85)
  46. self.a.gen_func_epilog()
  47. assert run_asm(self.a) == -123
  48. def test_load_neg_int_to_reg(self):
  49. self.a.gen_func_prolog()
  50. self.a.mc.gen_load_int(r.r0.value, -110)
  51. self.a.gen_func_epilog()
  52. assert run_asm(self.a) == -110
  53. def test_load_neg_int_to_reg2(self):
  54. self.a.gen_func_prolog()
  55. self.a.mc.gen_load_int(r.r0.value, -3)
  56. self.a.gen_func_epilog()
  57. assert run_asm(self.a) == -3
  58. def test_load_int1(self):
  59. self.a.gen_func_prolog()
  60. self.a.mc.gen_load_int(r.r0.value, 440)
  61. self.a.gen_func_epilog()
  62. assert run_asm(self.a) == 440
  63. def test_load_int2(self):
  64. self.a.gen_func_prolog()
  65. self.a.mc.gen_load_int(r.r0.value, 464)
  66. self.a.gen_func_epilog()
  67. assert run_asm(self.a) == 464
  68. def test_or(self):
  69. self.a.gen_func_prolog()
  70. self.a.mc.MOV_ri(r.r1.value, 8)
  71. self.a.mc.MOV_ri(r.r2.value, 8)
  72. self.a.mc.ORR_rr(r.r0.value, r.r1.value, r.r2.value, 4)
  73. self.a.gen_func_epilog()
  74. assert run_asm(self.a) == 0x88
  75. def test_sub(self):
  76. self.a.gen_func_prolog()
  77. self.a.mc.gen_load_int(r.r1.value, 123456)
  78. self.a.mc.SUB_ri(r.r0.value, r.r1.value, 123)
  79. self.a.gen_func_epilog()
  80. assert run_asm(self.a) == 123333
  81. def test_cmp(self):
  82. self.a.gen_func_prolog()
  83. self.a.mc.gen_load_int(r.r1.value, 22)
  84. self.a.mc.CMP_ri(r.r1.value, 123)
  85. self.a.mc.MOV_ri(r.r0.value, 1, c.LE)
  86. self.a.mc.MOV_ri(r.r0.value, 0, c.GT)
  87. self.a.gen_func_epilog()
  88. assert run_asm(self.a) == 1
  89. def test_int_le_false(self):
  90. self.a.gen_func_prolog()
  91. self.a.mc.gen_load_int(r.r1.value, 2222)
  92. self.a.mc.CMP_ri(r.r1.value, 123)
  93. self.a.mc.MOV_ri(r.r0.value, 1, c.LE)
  94. self.a.mc.MOV_ri(r.r0.value, 0, c.GT)
  95. self.a.gen_func_epilog()
  96. assert run_asm(self.a) == 0
  97. def test_simple_jump(self):
  98. self.a.gen_func_prolog()
  99. self.a.mc.MOV_ri(r.r1.value, 1)
  100. loop_head = self.a.mc.currpos()
  101. self.a.mc.CMP_ri(r.r1.value, 0) # z=0, z=1
  102. self.a.mc.MOV_ri(r.r1.value, 0, cond=c.NE)
  103. self.a.mc.MOV_ri(r.r1.value, 7, cond=c.EQ)
  104. self.a.mc.B_offs(loop_head, c.NE)
  105. self.a.mc.MOV_rr(r.r0.value, r.r1.value)
  106. self.a.gen_func_epilog()
  107. assert run_asm(self.a) == 7
  108. def test_jump(self):
  109. self.a.gen_func_prolog()
  110. self.a.mc.MOV_ri(r.r1.value, 1)
  111. loop_head = self.a.mc.currpos()
  112. self.a.mc.ADD_ri(r.r1.value, r.r1.value, 1)
  113. self.a.mc.CMP_ri(r.r1.value, 9)
  114. self.a.mc.B_offs(loop_head, c.NE)
  115. self.a.mc.MOV_rr(r.r0.value, r.r1.value)
  116. self.a.gen_func_epilog()
  117. assert run_asm(self.a) == 9
  118. def test_B_offs_imm(self):
  119. self.a.mc.PUSH([reg.value for reg in r.callee_saved_registers])
  120. self.a.mc.MOV_ri(r.r0.value, 0)
  121. self.a.mc.MOV_ri(r.r1.value, 0)
  122. self.a.mc.CMP_rr(r.r0.value, r.r1.value)
  123. pos = self.a.mc.currpos()
  124. self.a.mc.MOV_ri(r.r0.value, 123, cond=c.NE)
  125. for x in range(15):
  126. self.a.mc.POP(
  127. [reg.value for reg in r.callee_restored_registers], cond=c.NE)
  128. self.a.mc.MOV_ri(r.r1.value, 33)
  129. self.a.mc.MOV_ri(r.r0.value, 23)
  130. self.a.mc.CMP_rr(r.r0.value, r.r1.value)
  131. self.a.mc.B_offs(pos)
  132. assert run_asm(self.a) == 123
  133. def test_B_offs_reg(self):
  134. self.a.mc.PUSH([reg.value for reg in r.callee_saved_registers])
  135. self.a.mc.MOV_ri(r.r0.value, 0)
  136. self.a.mc.MOV_ri(r.r1.value, 0)
  137. self.a.mc.CMP_rr(r.r0.value, r.r1.value)
  138. pos = self.a.mc.currpos()
  139. self.a.mc.MOV_ri(r.r0.value, 123, cond=c.NE)
  140. for x in range(100):
  141. self.a.mc.POP(
  142. [reg.value for reg in r.callee_restored_registers], cond=c.NE)
  143. self.a.mc.MOV_ri(r.r1.value, 33)
  144. self.a.mc.MOV_ri(r.r0.value, 23)
  145. self.a.mc.CMP_rr(r.r0.value, r.r1.value)
  146. self.a.mc.B_offs(pos)
  147. assert run_asm(self.a) == 123
  148. def test_call_python_func(self):
  149. functype = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
  150. call_addr = rffi.cast(lltype.Signed, llhelper(functype, callme))
  151. self.a.gen_func_prolog()
  152. self.a.mc.MOV_ri(r.r0.value, 123)
  153. self.a.mc.BL(call_addr)
  154. self.a.gen_func_epilog()
  155. assert run_asm(self.a) == 133
  156. def test_bl_with_conditional_exec(self):
  157. functype = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
  158. call_addr = rffi.cast(lltype.Signed, llhelper(functype, callme))
  159. self.a.gen_func_prolog()
  160. self.a.mc.MOV_ri(r.r0.value, 123)
  161. self.a.mc.CMP_ri(r.r0.value, 1)
  162. self.a.mc.BL(call_addr, c.NE)
  163. self.a.gen_func_epilog()
  164. assert run_asm(self.a) == 133
  165. def test_mov_small_imm_loc_to_loc(self):
  166. self.a.gen_func_prolog()
  167. self.a.mov_loc_loc(imm(12), r.r0)
  168. self.a.gen_func_epilog()
  169. assert run_asm(self.a) == 12
  170. def test_mov_large_imm_loc_to_loc(self):
  171. self.a.gen_func_prolog()
  172. self.a.mov_loc_loc(imm(2478), r.r0)
  173. self.a.gen_func_epilog()
  174. assert run_asm(self.a) == 2478
  175. def test_load_store(self):
  176. x = 0x60002224
  177. self.a.gen_func_prolog()
  178. self.a.mc.gen_load_int(r.r1.value, x)
  179. self.a.mc.SUB_ri(r.sp.value, r.sp.value, 8)
  180. self.a.mc.MOV_ri(r.r3.value, 8)
  181. self.a.mc.STR_rr(r.r1.value, r.sp.value, r.r3.value)
  182. self.a.mc.LDR_ri(r.r0.value, r.sp.value, 8)
  183. self.a.mc.ADD_ri(r.sp.value, r.sp.value, 8)
  184. self.a.gen_func_epilog()
  185. assert run_asm(self.a) == x
  186. def test_stm(self):
  187. container = lltype.malloc(lltype.Array(lltype.Signed, hints={'nolength': True}), 10, flavor='raw')
  188. self.a.gen_func_prolog()
  189. self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, container))
  190. for x in range(10):
  191. self.a.mc.gen_load_int(x, x)
  192. self.a.mc.STM(r.ip.value, [x for x in range(10)])
  193. self.a.gen_func_epilog()
  194. run_asm(self.a)
  195. for x in range(10):
  196. assert container[x] == x
  197. lltype.free(container, flavor='raw')
  198. def test_ldm(self):
  199. container = lltype.malloc(lltype.Array(lltype.Signed, hints={'nolength': True}), 10, flavor='raw')
  200. for x in range(10):
  201. container[x] = x
  202. self.a.gen_func_prolog()
  203. self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, container))
  204. self.a.mc.LDM(r.ip.value, [x for x in range(10)])
  205. for x in range(1, 10):
  206. self.a.mc.ADD_rr(0, 0, x)
  207. self.a.gen_func_epilog()
  208. res = run_asm(self.a)
  209. assert res == sum(range(10))
  210. lltype.free(container, flavor='raw')
  211. def test_vstm(self):
  212. n = 14
  213. source_container = lltype.malloc(lltype.Array(longlong.FLOATSTORAGE,
  214. hints={'nolength': True}), n, flavor='raw')
  215. target_container = lltype.malloc(lltype.Array(longlong.FLOATSTORAGE,
  216. hints={'nolength': True}), n, flavor='raw')
  217. for x in range(n):
  218. source_container[x] = longlong.getfloatstorage(float("%d.%d" % (x,x)))
  219. self.a.gen_func_prolog()
  220. for x in range(n):
  221. self.a.mc.ADD_ri(r.ip.value, r.ip.value, 8)
  222. self.a.mc.VLDR(n, r.ip.value)
  223. self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, target_container))
  224. self.a.mc.VSTM(r.ip.value, [x for x in range(n)])
  225. self.a.gen_func_epilog()
  226. run_asm(self.a)
  227. for d in range(n):
  228. res = longlong.getrealfloat(target_container[0]) == float("%d.%d" % (d,d))
  229. lltype.free(source_container, flavor='raw')
  230. lltype.free(target_container, flavor='raw')
  231. def test_vldm(self):
  232. n = 14
  233. container = lltype.malloc(lltype.Array(longlong.FLOATSTORAGE,
  234. hints={'nolength': True}), n, flavor='raw')
  235. for x in range(n):
  236. container[x] = longlong.getfloatstorage(float("%d.%d" % (x,x)))
  237. self.a.gen_func_prolog()
  238. self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, container))
  239. self.a.mc.VLDM(r.ip.value, [x for x in range(n)])
  240. for x in range(1, n):
  241. self.a.mc.VADD(0, 0, x)
  242. self.a.mc.VSTR(r.d0.value, r.ip.value)
  243. self.a.gen_func_epilog()
  244. res = run_asm(self.a)
  245. assert longlong.getrealfloat(container[0]) == sum([float("%d.%d" % (d,d)) for d in range(n)])
  246. lltype.free(container, flavor='raw')
  247. def test_vstm_vldm_combined(self):
  248. n = 14
  249. source_container = lltype.malloc(lltype.Array(longlong.FLOATSTORAGE,
  250. hints={'nolength': True}), n, flavor='raw')
  251. target_container = lltype.malloc(lltype.Array(longlong.FLOATSTORAGE,
  252. hints={'nolength': True}), n, flavor='raw')
  253. for x in range(n):
  254. source_container[x] = longlong.getfloatstorage(float("%d.%d" % (x,x)))
  255. self.a.gen_func_prolog()
  256. self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, source_container))
  257. self.a.mc.VLDM(r.ip.value, [x for x in range(n)])
  258. self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, target_container))
  259. self.a.mc.VSTM(r.ip.value, [x for x in range(n)])
  260. self.a.gen_func_epilog()
  261. run_asm(self.a)
  262. for d in range(n):
  263. res = longlong.getrealfloat(target_container[0]) == float("%d.%d" % (d,d))
  264. lltype.free(source_container, flavor='raw')
  265. lltype.free(target_container, flavor='raw')
  266. def callme(inp):
  267. i = inp + 10
  268. return i