PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/pypy/pypy/
Python | 575 lines | 487 code | 87 blank | 1 comment | 3 complexity | ea9ab69ac01ac7d3b3aaf48fe41395ec MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from rpython.rlib.objectmodel import instantiate
  2. from rpython.jit.backend.arm.assembler import AssemblerARM
  3. from rpython.jit.backend.arm.locations import imm, ConstFloatLoc
  4. from rpython.jit.backend.arm.locations import RegisterLocation, StackLocation
  5. from rpython.jit.backend.arm.locations import VFPRegisterLocation, get_fp_offset
  6. from rpython.jit.backend.arm.locations import RawSPStackLocation
  7. from rpython.jit.backend.arm.registers import lr, ip, fp, vfp_ip, sp
  8. from rpython.jit.backend.arm.conditions import AL
  9. from rpython.jit.backend.arm.arch import WORD
  10. from rpython.jit.metainterp.history import FLOAT
  11. import py
  12. class MockInstr(object):
  13. def __init__(self, name, *args, **kwargs):
  14. self.name = name
  15. self.args = args
  16. self.kwargs = kwargs
  17. def __call__(self, *args, **kwargs):
  18. self.args = args
  19. self.kwargs = kwargs
  20. def __repr__(self):
  21. return "%s %r %r" % (self.name, self.args, self.kwargs)
  22. __str__ = __repr__
  23. def __eq__(self, other):
  24. return (self.__class__ == other.__class__
  25. and self.name == other.name
  26. and self.args == other.args
  27. and self.kwargs == other.kwargs)
  28. mi = MockInstr
  29. # helper method for tests
  30. def r(i):
  31. return RegisterLocation(i)
  32. def vfp(i):
  33. return VFPRegisterLocation(i)
  34. def stack(i, **kwargs):
  35. return StackLocation(i, get_fp_offset(0, i), **kwargs)
  36. def stack_float(i, **kwargs):
  37. return StackLocation(i, get_fp_offset(0, i + 1), type=FLOAT)
  38. def imm_float(value):
  39. addr = int(value) # whatever
  40. return ConstFloatLoc(addr)
  41. def raw_stack(i):
  42. return RawSPStackLocation(i)
  43. def raw_stack_float(i):
  44. return RawSPStackLocation(i, type=FLOAT)
  45. class MockBuilder(object):
  46. def __init__(self):
  47. self.instrs = []
  48. def __getattr__(self, name):
  49. i = MockInstr(name)
  50. self.instrs.append(i)
  51. return i
  52. class MockRegalloc(object):
  53. def get_free_reg(self):
  54. return r('helper')
  55. class BaseMovTest(object):
  56. def setup_method(self, method):
  57. self.builder = MockBuilder()
  58. self.asm = instantiate(AssemblerARM)
  59. self.asm._regalloc = MockRegalloc()
  60. self.asm.mc = self.builder
  61. def validate(self, expected):
  62. result = self.builder.instrs
  63. assert result == expected
  64. def mov(self, a, b, expected=None):
  65. self.asm.regalloc_mov(a, b)
  66. self.validate(expected)
  67. class TestRegallocMov(BaseMovTest):
  68. def test_mov_imm_to_reg(self):
  69. val = imm(123)
  70. reg = r(7)
  71. expected = [mi('gen_load_int', 7, 123, cond=AL)]
  72. self.mov(val, reg, expected)
  73. def test_mov_large_imm_to_reg(self):
  74. val = imm(65536)
  75. reg = r(7)
  76. expected = [mi('gen_load_int', 7, 65536, cond=AL)]
  77. self.mov(val, reg, expected)
  78. def test_mov_imm_to_stacklock(self):
  79. val = imm(100)
  80. s = stack(7)
  81. expected = [
  82. mi('gen_load_int', lr.value, 100, cond=AL),
  83. mi('STR_ri', lr.value, fp.value, imm=s.value, cond=AL),
  84. ]
  85. self.mov(val, s, expected)
  86. def test_mov_big_imm_to_stacklock(self):
  87. val = imm(65536)
  88. s = stack(7)
  89. expected = [
  90. mi('gen_load_int', lr.value, 65536, cond=AL),
  91. mi('STR_ri', lr.value, fp.value, imm=s.value, cond=AL),
  92. ]
  93. self.mov(val, s, expected)
  94. def test_mov_imm_to_big_stacklock(self):
  95. val = imm(100)
  96. s = stack(8191)
  97. expected = [ mi('gen_load_int', lr.value, 100, cond=AL),
  98. mi('gen_load_int', ip.value, s.value, cond=AL),
  99. mi('STR_rr', lr.value, fp.value, ip.value, cond=AL),
  100. ]
  101. self.mov(val, s, expected)
  102. def test_mov_big_imm_to_big_stacklock(self):
  103. val = imm(65536)
  104. s = stack(8191)
  105. expected = [
  106. mi('gen_load_int', lr.value, 65536, cond=AL),
  107. mi('gen_load_int', ip.value, s.value, cond=AL),
  108. mi('STR_rr', lr.value, fp.value, ip.value, cond=AL),
  109. ]
  110. self.mov(val, s, expected)
  111. def test_mov_reg_to_reg(self):
  112. r1 = r(1)
  113. r9 = r(9)
  114. expected = [mi('MOV_rr', r9.value, r1.value, cond=AL)]
  115. self.mov(r1, r9, expected)
  116. def test_mov_reg_to_stack(self):
  117. s = stack(10)
  118. r6 = r(6)
  119. expected = [mi('STR_ri', r6.value, fp.value, imm=s.value, cond=AL)]
  120. self.mov(r6, s, expected)
  121. def test_mov_reg_to_big_stackloc(self):
  122. s = stack(8191)
  123. r6 = r(6)
  124. expected = [
  125. mi('gen_load_int', ip.value, s.value, cond=AL),
  126. mi('STR_rr', r6.value, fp.value, ip.value, cond=AL),
  127. ]
  128. self.mov(r6, s, expected)
  129. def test_mov_stack_to_reg(self):
  130. s = stack(10)
  131. r6 = r(6)
  132. expected = [mi('LDR_ri', r6.value, fp.value, imm=s.value, cond=AL)]
  133. self.mov(s, r6, expected)
  134. def test_mov_big_stackloc_to_reg(self):
  135. s = stack(8191)
  136. r6 = r(6)
  137. expected = [
  138. mi('gen_load_int', ip.value, 32940, cond=AL),
  139. mi('LDR_rr', r6.value, fp.value, ip.value, cond=AL),
  140. ]
  141. self.mov(s, r6, expected)
  142. def test_mov_float_imm_to_vfp_reg(self):
  143. f = imm_float(3.5)
  144. reg = vfp(5)
  145. expected = [
  146. mi('gen_load_int', ip.value, f.value, cond=AL),
  147. mi('VLDR', 5, ip.value, imm=0, cond=AL),
  148. ]
  149. self.mov(f, reg, expected)
  150. def test_mov_vfp_reg_to_vfp_reg(self):
  151. reg1 = vfp(5)
  152. reg2 = vfp(14)
  153. expected = [mi('VMOV_cc', reg2.value, reg1.value, cond=AL)]
  154. self.mov(reg1, reg2, expected)
  155. def test_mov_vfp_reg_to_stack(self):
  156. reg = vfp(7)
  157. s = stack_float(3)
  158. expected = [mi('VSTR', reg.value, fp.value, imm=192, cond=AL)]
  159. self.mov(reg, s, expected)
  160. def test_mov_vfp_reg_to_large_stackloc(self):
  161. reg = vfp(7)
  162. s = stack_float(800)
  163. expected = [
  164. mi('gen_load_int', ip.value, s.value, cond=AL),
  165. mi('ADD_rr', ip.value, fp.value, ip.value, cond=AL),
  166. mi('VSTR', reg.value, ip.value, cond=AL),
  167. ]
  168. self.mov(reg, s, expected)
  169. def test_mov_stack_to_vfp_reg(self):
  170. reg = vfp(7)
  171. s = stack_float(3)
  172. expected = [mi('VLDR', reg.value, fp.value, imm=192, cond=AL)]
  173. self.mov(s, reg, expected)
  174. def test_mov_big_stackloc_to_vfp_reg(self):
  175. reg = vfp(7)
  176. s = stack_float(800)
  177. expected = [
  178. mi('gen_load_int', ip.value, s.value, cond=AL),
  179. mi('ADD_rr', ip.value, fp.value, ip.value, cond=AL),
  180. mi('VSTR', reg.value, ip.value, cond=AL),
  181. ]
  182. self.mov(reg, s, expected)
  183. def test_unsopported_cases(self):
  184. py.test.raises(AssertionError,
  185. 'self.asm.regalloc_mov(imm(1), imm(2))')
  186. py.test.raises(AssertionError,
  187. 'self.asm.regalloc_mov(imm(1), imm_float(2))')
  188. py.test.raises(AssertionError,
  189. 'self.asm.regalloc_mov(imm(1), vfp(2))')
  190. py.test.raises(AssertionError,
  191. 'self.asm.regalloc_mov(imm(1), stack_float(2))')
  192. py.test.raises(AssertionError,
  193. 'self.asm.regalloc_mov(imm_float(1), imm(2))')
  194. py.test.raises(AssertionError,
  195. 'self.asm.regalloc_mov(imm_float(1), imm_float(2))')
  196. py.test.raises(AssertionError,
  197. 'self.asm.regalloc_mov(imm_float(1), r(2))')
  198. py.test.raises(AssertionError,
  199. 'self.asm.regalloc_mov(imm_float(1), stack(2))')
  200. py.test.raises(AssertionError,
  201. 'self.asm.regalloc_mov(r(1), imm(2))')
  202. py.test.raises(AssertionError,
  203. 'self.asm.regalloc_mov(r(1), imm_float(2))')
  204. py.test.raises(AssertionError,
  205. 'self.asm.regalloc_mov(r(1), stack_float(2))')
  206. py.test.raises(AssertionError,
  207. 'self.asm.regalloc_mov(r(1), vfp(2))')
  208. py.test.raises(AssertionError,
  209. 'self.asm.regalloc_mov(stack(1), imm(2))')
  210. py.test.raises(AssertionError,
  211. 'self.asm.regalloc_mov(stack(1), imm_float(2))')
  212. py.test.raises(AssertionError,
  213. 'self.asm.regalloc_mov(stack(1), stack(2))')
  214. py.test.raises(AssertionError,
  215. 'self.asm.regalloc_mov(stack(1), stack_float(2))')
  216. py.test.raises(AssertionError,
  217. 'self.asm.regalloc_mov(stack(1), vfp(2))')
  218. py.test.raises(AssertionError,
  219. 'self.asm.regalloc_mov(stack_float(1), imm(2))')
  220. py.test.raises(AssertionError,
  221. 'self.asm.regalloc_mov(stack_float(1), imm_float(2))')
  222. py.test.raises(AssertionError,
  223. 'self.asm.regalloc_mov(stack_float(1), r(2))')
  224. py.test.raises(AssertionError,
  225. 'self.asm.regalloc_mov(stack_float(1), stack(2))')
  226. py.test.raises(AssertionError,
  227. 'self.asm.regalloc_mov(stack_float(1), stack_float(2))')
  228. py.test.raises(AssertionError,
  229. 'self.asm.regalloc_mov(vfp(1), imm(2))')
  230. py.test.raises(AssertionError,
  231. 'self.asm.regalloc_mov(vfp(1), imm_float(2))')
  232. py.test.raises(AssertionError,
  233. 'self.asm.regalloc_mov(vfp(1), r(2))')
  234. py.test.raises(AssertionError,
  235. 'self.asm.regalloc_mov(vfp(1), stack(2))')
  236. class TestMovFromVFPLoc(BaseMovTest):
  237. def mov(self, a, b, c, expected=None):
  238. self.asm.mov_from_vfp_loc(a, b, c)
  239. self.validate(expected)
  240. def test_from_vfp(self):
  241. vr = vfp(10)
  242. r1 = r(1)
  243. r2 = r(2)
  244. e = [mi('VMOV_rc', r1.value, r2.value, vr.value, cond=AL)]
  245. self.mov(vr, r1, r2, e)
  246. def test_from_vfp_stack(self):
  247. s = stack_float(4)
  248. r1 = r(1)
  249. r2 = r(2)
  250. e = [
  251. mi('LDR_ri', r1.value, fp.value, imm=s.value, cond=AL),
  252. mi('LDR_ri', r2.value, fp.value, imm=s.value + WORD, cond=AL)]
  253. self.mov(s, r1, r2, e)
  254. def test_from_big_vfp_stack(self):
  255. s = stack_float(2049)
  256. r1 = r(1)
  257. r2 = r(2)
  258. e = [
  259. mi('gen_load_int', ip.value, s.value, cond=AL),
  260. mi('LDR_rr', r1.value, fp.value, ip.value, cond=AL),
  261. mi('ADD_ri', ip.value, ip.value, imm=WORD, cond=AL),
  262. mi('LDR_rr', r2.value, fp.value, ip.value, cond=AL),
  263. ]
  264. self.mov(s, r1, r2, e)
  265. def test_from_imm_float(self):
  266. i = imm_float(4)
  267. r1 = r(1)
  268. r2 = r(2)
  269. e = [
  270. mi('gen_load_int', ip.value, i.value, cond=AL),
  271. mi('LDR_ri', r1.value, ip.value, cond=AL),
  272. mi('LDR_ri', r2.value, ip.value, imm=4, cond=AL),
  273. ]
  274. self.mov(i, r1, r2, e)
  275. def test_unsupported(self):
  276. py.test.raises(AssertionError,
  277. 'self.asm.mov_from_vfp_loc(vfp(1), r(5), r(2))')
  278. py.test.raises(AssertionError,
  279. 'self.asm.mov_from_vfp_loc(stack(1), r(1), r(2))')
  280. py.test.raises(AssertionError,
  281. 'self.asm.mov_from_vfp_loc(imm(1), r(1), r(2))')
  282. py.test.raises(AssertionError,
  283. 'self.asm.mov_from_vfp_loc(r(1), r(1), r(2))')
  284. class TestMoveToVFPLoc(BaseMovTest):
  285. def mov(self, r1, r2, vfp, expected):
  286. self.asm.mov_to_vfp_loc(r1, r2, vfp)
  287. self.validate(expected)
  288. def mov_to_vfp_reg(self):
  289. vr = vfp(10)
  290. r1 = r(1)
  291. r2 = r(2)
  292. e = [mi('VMOV_cr', vr.value, r1.value, r2.value, cond=AL)]
  293. self.mov(vr, r1, r2, e)
  294. def test_to_vfp_stack(self):
  295. s = stack_float(4)
  296. r1 = r(1)
  297. r2 = r(2)
  298. e = [
  299. mi('STR_ri', r1.value, fp.value, imm=s.value, cond=AL),
  300. mi('STR_ri', r2.value, fp.value, imm=s.value + WORD, cond=AL)]
  301. self.mov(r1, r2, s, e)
  302. def test_from_big_vfp_stack(self):
  303. s = stack_float(2049)
  304. r1 = r(1)
  305. r2 = r(2)
  306. e = [
  307. mi('gen_load_int', ip.value, s.value, cond=AL),
  308. mi('STR_rr', r1.value, fp.value, ip.value, cond=AL),
  309. mi('ADD_ri', ip.value, ip.value, imm=4, cond=AL),
  310. mi('STR_rr', r2.value, fp.value, ip.value, cond=AL),
  311. ]
  312. self.mov(r1, r2, s, e)
  313. def unsupported(self):
  314. py.test.raises(AssertionError,
  315. 'self.asm.mov_from_vfp_loc(r(5), r(2), vfp(4))')
  316. py.test.raises(AssertionError,
  317. 'self.asm.mov_from_vfp_loc(r(1), r(2), stack(2))')
  318. py.test.raises(AssertionError,
  319. 'self.asm.mov_from_vfp_loc(r(1), r(2), imm(2))')
  320. py.test.raises(AssertionError,
  321. 'self.asm.mov_from_vfp_loc(r(1), r(2), imm_float(2))')
  322. py.test.raises(AssertionError,
  323. 'self.asm.mov_from_vfp_loc(r(1), r(1), r(2))')
  324. class TestRegallocPush(BaseMovTest):
  325. def push(self, v, e):
  326. self.asm.regalloc_push(v)
  327. self.validate(e)
  328. def test_push_imm(self):
  329. i = imm(12)
  330. e = [mi('gen_load_int', ip.value, 12, cond=AL),
  331. mi('PUSH', [ip.value], cond=AL)]
  332. self.push(i, e)
  333. def test_push_reg(self):
  334. r7 = r(7)
  335. e = [mi('PUSH', [r7.value], cond=AL)]
  336. self.push(r7, e)
  337. def test_push_imm_float(self):
  338. f = imm_float(7)
  339. e = [
  340. mi('gen_load_int', ip.value, 7, cond=AL),
  341. mi('VLDR', vfp_ip.value, ip.value, imm=0, cond=AL),
  342. mi('VPUSH', [vfp_ip.value], cond=AL)
  343. ]
  344. self.push(f, e)
  345. def test_push_stack(self):
  346. s = stack(7)
  347. e = [mi('LDR_ri', ip.value, fp.value, imm=s.value, cond=AL),
  348. mi('PUSH', [ip.value], cond=AL)
  349. ]
  350. self.push(s, e)
  351. def test_push_big_stack(self):
  352. s = stack(1025)
  353. e = [
  354. mi('gen_load_int', lr.value, s.value, cond=AL),
  355. mi('LDR_rr', ip.value, fp.value, lr.value, cond=AL),
  356. mi('PUSH', [ip.value], cond=AL)
  357. ]
  358. self.push(s, e)
  359. def test_push_vfp_reg(self):
  360. v1 = vfp(1)
  361. e = [mi('VPUSH', [v1.value], cond=AL)]
  362. self.push(v1, e)
  363. def test_push_stack_float(self):
  364. sf = stack_float(4)
  365. e = [
  366. mi('VLDR', vfp_ip.value, fp.value, imm=196, cond=AL),
  367. mi('VPUSH', [vfp_ip.value], cond=AL),
  368. ]
  369. self.push(sf, e)
  370. def test_push_large_stackfloat(self):
  371. sf = stack_float(1000)
  372. e = [
  373. mi('gen_load_int', ip.value, sf.value, cond=AL),
  374. mi('ADD_rr', ip.value, fp.value, ip.value, cond=AL),
  375. mi('VLDR', vfp_ip.value, ip.value, cond=AL),
  376. mi('VPUSH', [vfp_ip.value], cond=AL),
  377. ]
  378. self.push(sf, e)
  379. class TestRegallocPop(BaseMovTest):
  380. def pop(self, loc, e):
  381. self.asm.regalloc_pop(loc)
  382. self.validate(e)
  383. def test_pop_reg(self):
  384. r1 = r(1)
  385. e = [mi('POP', [r1.value], cond=AL)]
  386. self.pop(r1, e)
  387. def test_pop_vfp_reg(self):
  388. vr1 = vfp(1)
  389. e = [mi('VPOP', [vr1.value], cond=AL)]
  390. self.pop(vr1, e)
  391. def test_pop_stackloc(self):
  392. s = stack(12)
  393. e = [
  394. mi('POP', [ip.value], cond=AL),
  395. mi('STR_ri', ip.value, fp.value, imm=s.value, cond=AL)]
  396. self.pop(s, e)
  397. def test_pop_big_stackloc(self):
  398. s = stack(1200)
  399. e = [
  400. mi('POP', [ip.value], cond=AL),
  401. mi('gen_load_int', lr.value, s.value, cond=AL),
  402. mi('STR_rr', ip.value, fp.value, lr.value, cond=AL),
  403. ]
  404. self.pop(s, e)
  405. def test_pop_float_stackloc(self):
  406. s = stack_float(12)
  407. e = [
  408. mi('VPOP', [vfp_ip.value], cond=AL),
  409. mi('VSTR', vfp_ip.value, fp.value, imm=s.value, cond=AL),
  410. ]
  411. self.pop(s, e)
  412. def test_pop_big_float_stackloc(self):
  413. s = stack_float(1200)
  414. e = [
  415. mi('VPOP', [vfp_ip.value], cond=AL),
  416. mi('gen_load_int', ip.value, s.value, cond=AL),
  417. mi('ADD_rr', ip.value, fp.value, ip.value, cond=AL),
  418. mi('VSTR', vfp_ip.value, ip.value, cond=AL),
  419. ]
  420. self.pop(s, e)
  421. def test_unsupported(self):
  422. py.test.raises(AssertionError, 'self.asm.regalloc_pop(imm(1))')
  423. py.test.raises(AssertionError, 'self.asm.regalloc_pop(imm_float(1))')
  424. class TestRawStackLocs(BaseMovTest):
  425. def test_unsupported(self):
  426. py.test.raises(AssertionError, 'self.asm.regalloc_mov(raw_stack(0), imm(1))')
  427. py.test.raises(AssertionError, 'self.asm.regalloc_mov(raw_stack(0), imm_float(1))')
  428. py.test.raises(AssertionError, 'self.asm.regalloc_mov(raw_stack(0), vfp(1))')
  429. py.test.raises(AssertionError, 'self.asm.regalloc_mov(raw_stack(0), stack(1))')
  430. py.test.raises(AssertionError, 'self.asm.regalloc_mov(raw_stack(0), stack_float(1))')
  431. py.test.raises(AssertionError, 'self.asm.regalloc_mov(imm_float(1), raw_stack(1))')
  432. py.test.raises(AssertionError, 'self.asm.regalloc_mov(imm(1), raw_stack_float(1))')
  433. py.test.raises(AssertionError, 'self.asm.regalloc_mov(vfp(1), raw_stack(1))')
  434. py.test.raises(AssertionError, 'self.asm.regalloc_mov(r(1), raw_stack_float(1))')
  435. py.test.raises(AssertionError, 'self.asm.regalloc_mov(stack_float(1), raw_stack(1))')
  436. py.test.raises(AssertionError, 'self.asm.regalloc_mov(stack(1), raw_stack_float(1))')
  437. def test_from_imm(self):
  438. s = raw_stack(1024)
  439. i = imm(999)
  440. e = [
  441. mi('gen_load_int', lr.value, i.value, cond=AL),
  442. mi('gen_load_int', ip.value, s.value, cond=AL),
  443. mi('STR_rr', lr.value, sp.value, ip.value, cond=AL),
  444. ]
  445. self.mov(i, s, e)
  446. def test_from_vfp_imm(self):
  447. s = raw_stack_float(1024)
  448. i = imm_float(999)
  449. e = [
  450. mi('gen_load_int', ip.value, i.value, cond=AL),
  451. mi('VLDR', vfp_ip.value, ip.value, cond=AL, imm=0),
  452. mi('gen_load_int', ip.value, s.value, cond=AL),
  453. mi('ADD_rr', ip.value, sp.value, ip.value, cond=AL),
  454. mi('VSTR', vfp_ip.value, ip.value, cond=AL),
  455. ]
  456. self.mov(i, s, e)
  457. def test_from_reg(self):
  458. s = raw_stack(1024)
  459. reg = r(10)
  460. e = [mi('gen_load_int', ip.value, s.value, cond=AL),
  461. mi('STR_rr', reg.value, sp.value, ip.value, cond=AL),
  462. ]
  463. self.mov(reg, s, e)
  464. def test_from_vfp_reg(self):
  465. s = raw_stack_float(1024)
  466. reg = vfp(10)
  467. e = [mi('gen_load_int', ip.value, s.value, cond=AL),
  468. mi('ADD_rr', ip.value, sp.value, ip.value, cond=AL),
  469. mi('VSTR', reg.value, ip.value, cond=AL),
  470. ]
  471. self.mov(reg, s, e)
  472. def test_from_stack(self):
  473. s = raw_stack(1024)
  474. reg = stack(10)
  475. e = [mi('LDR_ri', ip.value, fp.value, imm=216, cond=AL),
  476. mi('gen_load_int', lr.value, s.value, cond=AL),
  477. mi('STR_rr', ip.value, sp.value, lr.value, cond=AL),
  478. ]
  479. self.mov(reg, s, e)
  480. def test_from_vfp_stack(self):
  481. s = raw_stack_float(1024)
  482. reg = stack_float(10)
  483. e = [mi('VLDR', vfp_ip.value, fp.value, imm=220, cond=AL),
  484. mi('gen_load_int', ip.value, s.value, cond=AL),
  485. mi('ADD_rr', ip.value, sp.value, ip.value, cond=AL),
  486. mi('VSTR', vfp_ip.value, ip.value, cond=AL),
  487. ]
  488. self.mov(reg, s, e)